Synchronization OpenCL和GPU全局同步

Synchronization OpenCL和GPU全局同步,synchronization,gpu,global,Synchronization,Gpu,Global,是否有人尝试过“通过快速屏障同步进行块间gpu通信”一文中描述的gpu_同步功能?所有描述的代码看起来都很简单,很容易实现,但它一直冻结了我的GPU。我肯定我在做傻事,但我看不出是什么。有人能帮我吗 我使用的策略是“GPU无锁同步”一节中描述的策略,下面是我实现的OpenCL源代码: static void globalSync(uint iGoalValue, volatile __global int *globalSyncFlagsIN,

是否有人尝试过“通过快速屏障同步进行块间gpu通信”一文中描述的gpu_同步功能?所有描述的代码看起来都很简单,很容易实现,但它一直冻结了我的GPU。我肯定我在做傻事,但我看不出是什么。有人能帮我吗

我使用的策略是“GPU无锁同步”一节中描述的策略,下面是我实现的OpenCL源代码:

static void globalSync(uint iGoalValue,
                   volatile __global int *globalSyncFlagsIN,
                   volatile __global int *globalSyncFlagsOUT)
{
 const size_t iLocalThreadID  = get_local_id(0);
 const size_t iWorkGroupID    = get_group_id(0);
 const size_t iWorkGroupCount = get_num_groups(0);

 //Only the first thread on each SM is used for synchronization
 if (iLocalThreadID == 0)
 { globalSyncFlagsIN[iWorkGroupID] = iGoalValue; }

 if (iWorkGroupID == 0)
 {
  if (iLocalThreadID < iWorkGroupCount)
  {
   while (globalSyncFlagsIN[iLocalThreadID] != iGoalValue) {
    // Nothing to do here
   }
  }

  barrier(CLK_GLOBAL_MEM_FENCE);

  if (iLocalThreadID < iWorkGroupCount)
  { globalSyncFlagsOUT[iLocalThreadID] = iGoalValue; }
 }

 if (iLocalThreadID == 0)
 {
  while (globalSyncFlagsOUT[iWorkGroupID] != iGoalValue) {
   // Nothing to do here 
  }
 }

 barrier(CLK_GLOBAL_MEM_FENCE);
} 
static void globalSync(uint IGOLVALUE,
volatile\uuu global int*globalSyncFlagsIN,
volatile(全局int*globalSyncFlagsOUT)
{
const size\u t iLocalThreadID=get\u local\u id(0);
const size\u t iWorkGroupID=get\u group\u id(0);
const size\u t iWorkGroupCount=get\u num\u groups(0);
//每个SM上只有第一个线程用于同步
如果(iLocalThreadID==0)
{globalSyncFlagsIN[iWorkGroupID]=iGoalValue;}
如果(iWorkGroupID==0)
{
if(iLocalThreadID

提前感谢。

我还没有试着运行代码,但是上面提到的文章中的代码从CUDA到OpenCL的直接翻译是:

{  
    int tid_in_blk = get_local_id(0) * get_local_size(1)
        + get_local_id(1);
    int nBlockNum = get_num_groups(0) * get_num_groups(1);
    int bid = get_group_id(0) * get_num_groups(1) + get_group_id(1);


    if (tid_in_blk == 0) {
        Arrayin[bid] = goalVal;
    }

    if (bid == 1) {
        if (tid_in_blk < nBlockNum) {
            while (Arrayin[tid_in_blk] != goalVal){

            }
        }
        barrier(CLK_LOCAL_MEM_FENCE);

        if (tid_in_blk < nBlockNum) {
            Arrayout[tid_in_blk] = goalVal;
        }
    }

    if (tid_in_blk == 0) {
        while (Arrayout[bid] != goalVal) {

        }
    }
}
{
int tid_in_blk=获取本地id(0)*获取本地大小(1)
+获取本地id(1);
int nBlockNum=获取数量组(0)*获取数量组(1);
int bid=get_group_id(0)*get_num_group(1)+get_group_id(1);
如果(tid_in_blk==0){
Arrayin[投标]=目标值;
}
如果(投标=1){
如果(tid_in_blk

请注意线程和组ID的区别,以及使用本地内存屏障而不是全局内存屏障的区别。

请仔细考虑我的最后一句话。当然,Arrayin和Arrayout应该位于_全局内存中,以便来自不同块的线程可以通过它进行通信。内存围栏仍然应该是本地的,因为只有组1中的线程是同步的。我编辑了答案。另外,确保数组的长度至少等于块的数量。我怀疑的是文章中描述的最后一个同步障碍。我通过将算法从代码中删除,成功地使其工作,但为什么作者建议使用它呢?真的有必要吗?不知怎的,我错过了文章中最后一个uu synchthreads()。或许我一直在浏览这篇文章的另一个版本。据我所知,即使最后没有显式的组间同步,代码(我指的是全局同步)也必须按预期工作。作者可能已经添加了它,以便在从函数返回之前对齐组内的线程,这可能是一件好事。有趣的是:该算法在我的5870m上运行完美,但冻结了我的R9 290X。完全相同的代码和两种不同的行为。你知道发生了什么事吗?