我在OpenCL 1.2中遇到了问题。
看,我在内核中有一个数组__global
,组大小为1000。
问题是atomic_add()
功能无法正常工作。
我的内核代码是:
__kernel void kernelfunction(__global uint32_t* buffer){
buffer[3] = 100;
atomic_add(&buffer[3], 1);
...
}
如果我创建了1000个线程,我希望buffer[3]
的值为1100,我是对的吗?
但程序的行为是未定义的。
有时它会是1100,有时是1064,有时是1093 ......
我尝试过:
我还启用了如下的opencl扩展名:
#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
但问题仍然存在。
在另一个项目中,我创建了一个简单的opencl项目,atomic_add
正常工作,我几乎检查了整个项目配置,但我不知道问题在哪里。
答案 0 :(得分:3)
如果没有原子,一个简单的访问在完成同一个元素时会有竞争条件,更糟糕的是,所有数据都可以按计算单元进行缓存,直到内核结束时才会更新。
buffer[3] = 100;
这是未定义的行为。结果甚至可能是101;
如果没有同步命令,即使同一本地组中的线程也不能拥有真实数据。
初始化应该由主机进行,因为gpu会同时运行线程。不连续,不包括原子。或者,您初始化其自己的组(从其他组不可见)并在此之后添加barrier(CLK_GLOBAL_MEM_FENCE)
,以便同一组中的其他线程可以正确查看。