OpenCL - 重用全局内存

时间:2014-03-10 03:49:58

标签: memory opencl global read-write

这是一个看似基本的问题,我无法通过大量的反复试验来解决问题。我有一个内核,它使用两个全局r / w缓冲区和一个本地 - 它从第一个缓冲区获取输入,使用第二个缓冲区对其进行伪排序以进行临时存储,并最终将其复制回第一个一定的顺序。 (剥离)代码如下:

struct PACKET_POINTER {
       int packetIndex;
       int currentCell;
};

#define RPC_DIV_BUCKET 100
__kernel void PseudoSort(__global struct PACKET_POINTER * in,__global struct PACKET_POINTER * out, __local struct PACKET_POINTER * aux) {
  int i = get_local_id(0);
  int wg = get_local_size(0);
  int gid = get_global_id(0);
  int offset = get_group_id(0) * wg;

  aux[i] = in[i+offset];
  barrier(CLK_LOCAL_MEM_FENCE);
  //-----
  //Irrelevant code block here
  //----- 
  out[(gid%1024)*RPC_DIV_BUCKET + (gid/1024)] = aux[i];
}

检索父C程序中“out”缓冲区的内容没有问题。但是,当我向内核添加以下行时:

    barrier(CLK_GLOBAL_MEM_FENCE);
    in[gid] = out[gid];

并尝试读取“in”缓冲区,它在第一次执行时主要显示垃圾值,但如果.exe第二次运行而没有修改,则会有预期的数据。我在内核调用和缓冲区读取之间进行clFinish(命令)调用,因此它应该在任何读取尝试之前运行完成。显而易见的我在这里不见了?提前感谢帮助 - 如果我在此之前发生了解决方案,我会发布解决方案。

1 个答案:

答案 0 :(得分:1)

CLK_GLOBAL_MEM_FENCE仅在工作组中同步。没有办法在所有工作组之间放置一个同步的屏障(例如,它只在具有相同group_id的那些线程中同步)。

那里你有竞争条件。作为示例,当global_id为1时,写入进入[100]。然后该特定线程从out [1]读取并写入[1]。但是out [1]仅在global_id 1024处写入。几乎可以肯定在不同的工作组中。所以你会读到垃圾,因为第一个工作组将要在out [1]开始编写之前完成。