2013-09-27 35 views
0

我正在关注this教程,除了关于如何创建信号灯的最后一个例子,我一直都很赞。逻辑非常简单,但我无法弄清楚为什么这个内核导致无限循环。如何防止OpenCL信号中的死锁?

myKernel.cl

#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable 
void GetSemaphor(__global int * semaphor, __global int * data) { 
    int occupied = atom_xchg(semaphor, 1); 
    int realityCheck = 0; 
    while(occupied == 1 && realityCheck++ < 100000) 
     occupied = atom_xchg(semaphor, 1); 
} 

void ReleaseSemaphor(__global int * semaphor) 
{ 
    int prevVal = atom_xchg(semaphor, 0); 
} 

__kernel void myKernel(__global int* data, __global int* semaphor) 
{ 
    // semaphor[0] is set to 0 on the host. 
    GetSemaphor(&semaphor[0], data); 
    data[0]++; 
    ReleaseSemaphor(&semaphor[0]); 
} 

这是:

的OpenCL 1.2

FULL_PROFILE

上的Quadro NVS 290具有

* cl_khr_global_int32_base_atomics CL _khr_global_int32_extended_atomics

回答

2

你所反馈的那个教程是错误的,并且不会在GPU设备上工作。由于硬件架构。

任何阻止工作组内工作项的同步机制都不起作用。由于阻塞状态将影响整个工作组,产生无限循环。

您只能在工作组大小为1或者跨工作组的情况下完成这些工作。

+0

很好的答案,谢谢! – user1873073

+1

同意。问题是第一个工作项获得信号量,然后其余工作项都不能继续执行,除了在大多数体系结构中,许多工作项都绑在一起成为warp或wavefront,并且必须以锁步,所以通过阻止其他工作项目,您会使整个warp/wavefront发生死锁,从而导致工作组发生死锁,从而导致内核死锁。 – Dithermaster