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

标签 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。好像这些值已经向后移动了几个元素。为什么?这是怎么回事?

最佳答案

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

你放

cl::NDRange(200 / numberOfDevices)

作为范围

但你没有放

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

作为每个设备的偏移量。

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

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

关于c++ - OpenCL C++ - 线程 64 后数组的内存管理错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39873496/

相关文章:

c++ - 如何初始化字节数组的映射?

r - R 中字符的对象大小 - R 全局字符串池如何工作?

c# - 创建堆栈大小为默认值 50 倍的线程时有什么危险?

python - 如何确定 SLURM 中 python 脚本步骤内存超出的时间点

c# - 如何在 C++ boolean 表达式中计算指针?

c++ - 枚举成员值的类型特征

c++ - 是否有任何替代方法来实现 WebRTC SFU,只有 1 个上传流?

java - 使用线程实时更新 JTextArea

java - 在多线程应用程序中,是否应该使用 ReadWriteLock 锁定基本类型的 getter/setter?

c++ - 线程局部变量的初始化