OpenCL - 同步和信号?

时间:2016-01-20 12:50:24

标签: multithreading synchronization opencl

我想在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中不起作用。

有谁知道,如何修复此代码?

1 个答案:

答案 0 :(得分:1)

您正在将GPU计算视为多线程计算,这是完全错误的方法。

原因在于GPU计算所有"线程" (实际上它们是工作项目),同时运行。工作项无法进入区域,运行代码,而其他工作项正在执行其他操作。

因此,在GPU中进行任何类型的分支都是一个糟糕的想法,因为它会降低您的应用程序速度,使GPU运行所有分支,即使某些项目在这种情况下不进入。

针对您的具体情况:

您在内核中遇到了死锁,因为您正在分支中创建障碍。在一个工作项进入后,将等待所有其他工作项进入。如果那种情况永远不会发生,那么你就陷入了僵局。

检查屏障命令:https://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/barrier.html

  

如果障碍在条件语句中,那么所有工作项必须输入条件,如果任何工作项进入条件语句并执行障碍。