OpenCL C ++ - 线程64之后的数组的内存管理错误

时间:2016-10-05 12:05:35

标签: c++ multithreading memory kernel opencl

我在使用openCL C ++时遇到了这个非常奇怪的问题。问题是我有100个线程正在访问每个100大小数组的一个元素。从0到63,没有问题,每个线程正在计算和更新数组元素的值。但是当它到达线程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 []数组,其值相同。然后我对每个线程的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 []数组的每个元素,并将它们连续放回更大的数组(线程数* 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。好像这些值已经向后移动了几个元素。为什么?这是怎么回事?

2 个答案:

答案 0 :(得分:0)

如果多个设备在同一个阵列上工作,则会出现问题,

你把

cl::NDRange(200 / numberOfDevices)

作为范围

但你没有放

cl::NDRange((200 / numberOfDevices)*deviceIndex)

作为每个设备的偏移量。

所有设备都试图写入相同位置而不是相邻组。

此外,您不会检查内核中的总线程数是否小于数组长度,因此某些线程可能会尝试写出超出范围。

答案 1 :(得分:0)

所以我找到了解决问题的方法:

问题在于即使每个线程都有自己的application/json数组存储在value[]数组中的副本:

tempValue[]

数组中的值在线程64之后被搞砸了。所以我做的是在主机代码(// 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]; } )外面创建了一个更大的值数组,然后复制了数组的第一部分其余的99个零件我把它发送到设备。然后我使用索引使每个线程访问其自己的value []数组部分。

它解决了这个问题!