繁体   English   中英

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

[英]OpenCL C++ - memory management error for array after thread 64

在使用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。就好像这些值已向后移动了几个元素。 为什么? 这里发生了什么?

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

你把

cl::NDRange(200 / numberOfDevices)

作为范围

但是你不放

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

作为每个设备的偏移量。

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

另外,您不检查内核中的总线程数是否少于数组长度,因此某些线程可能会尝试写越界。

因此,我找到了解决问题的方法:

问题在于,即使每个线程都有存储在tempValue[]数组中的value[]数组的副本:

// 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];
}

线程64之后,数组中的值被弄乱了。所以我要做的是在主机代码中创建了一个更大的值外部数组( sizeOf(value) * 100 ),然后将数组的第一部分复制到剩下99个零件,我寄给了设备。 然后,我使每个线程都使用索引访问它自己的value []数组部分。

它解决了问题!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM