我有一个使用全局uint数组的内核,我想使用OpenCL中的atom_or
函数从所有线程访问和更改该数组中的条目。
代码:
void SetMove(int c, uint m, volatile __global uint *prevmove)
{
uint idx = c >> 4;
uint mask = m << (2 * (c & 15));
atom_or(&prevmove[idx], mask);
}
我正在使用OpenCL实现BFS算法。这是在'wave'中完成的,其中在每个wave中,分析状态的数组in
。每个GPU线程评估一个状态,找到它的后继,并将它们放在不同的数组out
中。在wave结束时,out
的内容位于in
。
prevmove
数组用于跟踪您在特定状态下应该执行的操作以查找目标状态。当线程找到新状态时,SetMove
函数会更新prevmove
。
现在的问题是:
结果总是不确定的。如果我使用普通的非原子atom_or
运算符进行|=
运算,则内核的行为完全相同。我已经通过检查算法终止时prevmove
中有多少条目非零而测试了这一点。每次运行我的程序时都会有所不同。
导致我的问题是由于没有正确实现atom_or
还是其他原因?
(我的内核中有#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable
。)