(Py)OpenCl:第16个元素后的错误扫描结果

(Py)OpenCl:第16个元素后的错误扫描结果,opencl,Opencl,因此,我开始研究Hillis-Steele扫描算法,以便获得数组的运行和,对于元素少于17个的数组(N

因此,我开始研究Hillis-Steele扫描算法,以便获得数组的运行和,对于元素少于17个的数组(
N<17
),它似乎工作得很好,但在这之后,我经常得到错误的结果,尽管不总是这样。
N
越大,返回错误结果的概率越高,在
N=40
左右后,返回结果的不正确率达到100%。数组在第16个元素之后开始偏离真值

这是我的密码:

__kernel void scan(__global double * a, __const int N, __global double * sum_a, __global double * temp) {

    //
    // Hillis - Steele scan algorithm
    //

    int id = get_global_id(0); // Thread id

    temp[id] = a[id]; // Copying the content of a to a temporary array
    barrier(CLK_GLOBAL_MEM_FENCE); // Waiting for all threads to finish

    for(int offset = 1; offset < N; offset *= 2) { // At each increment, double 'offset'

        if(id >= offset)
            temp[id] += temp[id - offset]; // Add 'id' to a neighbour a distance 'offset' away
        else
            temp[id] = temp[id]; // Copy the previous value

        barrier(CLK_GLOBAL_MEM_FENCE); // Synchronising
    }
    sum_a[id] = temp[id]; // Storing final result
}
\uuuuu内核无效扫描(\uuuu全局双精度*a,\uuuu常量int N,\uuuu全局双精度*sum\u a,\uuuu全局双精度*temp){
//
//Hillis-Steele扫描算法
//
int id=get_global_id(0);//线程id
temp[id]=a[id];//将a的内容复制到临时数组
barrier(CLK_GLOBAL_MEM_FENCE);//等待所有线程完成
对于(int offset=1;offset=偏移量)
temp[id]+=temp[id-offset];//将“id”添加到距离“offset”较远的邻居
其他的
temp[id]=temp[id];//复制上一个值
屏障(CLK_GLOBAL_MEM_FENCE);//同步
}
sum_a[id]=temp[id];//存储最终结果
}

有人知道这里出了什么问题吗?

在OpenCL中,您只能在工作组中的工作项之间进行同步,不能全局同步。您的内核似乎依赖于全局同步。

我认为
屏障(CLK\u global\u MEM\u FENCE)
在所有线程之间同步,而不是
屏障(CLK\u LOCAL\u MEM\u FENCE)
?你有什么建议可以让它正常工作吗?CLK_GLOBAL/LOCAL_MEM_FENCE与被同步的内存类型有关,而不是同步的范围(它总是只在工作组内)。进行全局同步的唯一方法是使用单独的内核。因此,将您的内核(在您有同步的地方)拆分为多个内核,并将每个内核排队。在第一个内核的所有工作组都完成之前,第二个内核不会启动。