我想在OpenCL中使用同步信号设置来确保只有一个线程可以进入关键内核部分。 这是我到目前为止的代码:
void sync(int barrierID) {
int ID = get_global_id(0);
barrier(CLK_GLOBAL_MEM_FENCE);
while (ID - barrierID != 0) {
barrier(CLK_GLOBAL_MEM_FENCE);
}
}
//critical part
void signal(int threadCount, int barrierID) {
barrierID++;
barrier(CLK_GLOBAL_MEM_FENCE);
while (barrierID != threadCount) {
barrier(CLK_GLOBAL_MEM_FENCE);
}
barrierID = 0;
}
使用threadcount表示线程数量,wnat访问关键部分,barrierID是计算通过此部分的线程数。
不幸的是,这段代码在OpenCL中不起作用。
有谁知道,如何修复此代码?
答案 0 :(得分:1)
您正在将GPU计算视为多线程计算,这是完全错误的方法。
原因在于GPU计算所有"线程" (实际上它们是工作项目),同时运行。工作项无法进入区域,运行代码,而其他工作项正在执行其他操作。
因此,在GPU中进行任何类型的分支都是一个糟糕的想法,因为它会降低您的应用程序速度,使GPU运行所有分支,即使某些项目在这种情况下不进入。
针对您的具体情况:
您在内核中遇到了死锁,因为您正在分支中创建障碍。在一个工作项进入后,将等待所有其他工作项进入。如果那种情况永远不会发生,那么你就陷入了僵局。
检查屏障命令:https://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/barrier.html
如果障碍在条件语句中,那么所有工作项必须输入条件,如果任何工作项进入条件语句并执行障碍。