我是OpenCL的新手,并尝试在OpenCL中使用全局内存进行2D扫描。
我在输出数组中有一些无效值,这令人怀疑 如果全局内存是连续的。因为通过运行以下内核,我在输出数组中找到了一些垃圾值。
这是我的内核。输入和输出都是8乘8的2-d阵列。
#define SWAP(a,b) {__global uint *tmp=a;a=b;b=tmp;}
__kernel void 2dScan(
const __global uint * const input,
__global uint * const output,
__global uint *lb,
__global uint *lc
)
{
const uint x = get_global_id(0);
const uint y = get_global_id(1);
const uint xm = get_global_size(0);
const uint ym = get_global_size(1);
uint gs = get_global_size(0) * get_global_size(1);
uint index = y * xm + x;
lb[index] = lc[index] = input[index];
barrier(CLK_GLOBAL_MEM_FENCE);
for(uint s = 1; s < gs; s <<= 1) {
if(index > (s-1)) {
lc[index] = lb[index]+lb[index-s];
} else {
lc[index] = lb[index];
}
barrier(CLK_GLOBAL_MEM_FENCE);
SWAP(lb,lc);
}
output[index]= lb[index];
}
非常感谢你能提出一些建议。
答案 0 :(得分:0)
我怀疑,什么是垃圾价值?未初始化的或不正确的?
在我看来,你的for循环中存在问题。您的访问不是确定性的,也就是说,您无法确定结果,例如输出[2]。
例如,工作项#2在循环内执行(s = 1):lc [2] = lb [2] + lb [1];
好的,问题是:lb [1]的值是否已经被工作项#1修改了?您的屏障同步了属于同一工作组的工作项。我认为lc[index] = lb[index]+lb[index-s];
中的访问超出了工作组的“限制”范围,因为s
值导致了非确定性问题。
答案 1 :(得分:0)
您正在覆盖每个工作项中的lb
和lc
。因此,结果是未定义的,因为OpenCL在全局项之间没有同步。 barrier(CLK_GLOBAL_MEM_FENCE);
在全局内存范围内同步本地工作组。
您将获得的结果基于计划模式,并且无法以任何方式预测。但是,它只会发生在本地组边界。
您需要更改算法。