openCL C++で作業しているときにこの非常に奇妙な問題が発生しました。問題は、100個のスレッドのそれぞれが100個のサイズの配列の1つの要素にアクセスしていることです。 0から63まで、問題はなく、各スレッドは配列の要素の値を適切に計算し更新します。ここでOpenCL C++ - スレッド64の後の配列のメモリ管理エラー
私はカーネルを呼び出す方法です。しかし、それは64のスレッド化になったときに、それが台無しにし、他のいくつかの値を使用して値を更新...:
kernelGA(cl::EnqueueArgs(queue[iter],
cl::NDRange(200/numberOfDevices)),
d_value,
d_doubleParameters,
buf_half_population, and so on...)
カーネル側では、私はそれぞれにアクセスしていますが
__kernel void kernelGA (__global double * value,
__global double * doubleParameters,
__global double * population,
__global double * scores, and so on...)
int idx = get_global_id(0); // This gives me 100 threads for each device. (I have two devices)
int size_a = 50;
double tempValue[size_a];
// Copying the global "value" into local array so each thread has its own copy.
for (int i = 0; i < size_a; i++) {
tempValue[i] = value[i];
}
この時点で、各スレッドは同じ値を持つ独自のtempValue []配列を持つようになりました。そして、私はこの後
// Applying some computations on tempValue and changing the values for each copy of tempValue for each thread.
tempValue[i] = some calculations for each thread...
...各スレッドのtempValue []配列の値のいくつかの計算や数式を適用し、私は、スレッドごとにtempValue []配列の各要素にアクセスし、中に継続的にそれらを元に戻しますより大きなサイズの配列(スレッドの数* size_a)。念頭に置いておくと、配列のためのインデックスは次のように行くこと:0,1、2、3、...のように...
for (int i = 0; i < size_a; i++) {
totalArray[(idx * size_a) + i] = tempvalue[i];
}
だから私は、カーネルの外totalArrayの答えを取得し、それらを印刷するとき最初の64個(0〜63)のスレッドはtotalArray []に値を適切に配置しています。しかし、64を超えると、索引付けが乱れてしまいます。私は索引だけを印刷し、索引はすべてのスレッドに対して適切にアクセスしているため、索引付けは正確ではありません。しかし、値が混乱しているようです...
たとえば、スレッド0-63の3番目、4番目、5番目および6番目の要素の値は、それぞれ50,60,70および80です。しかし、スレッド64以降では、第3、第4、第5および第6要素の値は80,90,100,110である。あたかも値が逆方向に少数の要素だけシフトされているかのように。どうして?ここで何が起こっているのですか?
合計スレッド数が配列の長さよりも小さいかどうかを確認するにはどうすればよいですか? –