在OpenCL内核中是否存在使某个特定线程在某些条件下等待其他线程的方法

时间:2012-03-13 17:50:23

标签: opencl


    __kernel
    void example(__global int *a, __global int *dependency, uint cols)
    {
        int j = genter code hereet_global_id(0);
        int i = get_global_id(1);
        if(i > 0 && j > 0)
        {
            while(1) 
        {
           test = 1;                
            }
            //Wait for the dependents

        -----------------------------

        --------------------------
        }
    }

在上面的内核代码中,为什么在没有无限循环的所有线程中跳过while循环。对此有任何想法。 我正在研究一些有趣的问题,需要一个线程等待一些其他线程根据某些条件完成,但每次在上面或while(wait_condition)在GPU上运行时都会被跳过。

是否还有其他方法可以使特定线程等待GPU上OpenCL内核中的其他线程?

提前致谢!

1 个答案:

答案 0 :(得分:3)

在高层,GPU是数据并行计算设备。他们喜欢在不同的数据上运行相同的任务。当他们的任务做不同的事情时,他们做得不好。

您的代码说明了任务并行问题。所以我的高级问题是你在解决什么类型的问题。如果这是一个任务并行问题,那么GPU可能不是最好的解决方案。多核CPU是否可以替代?

您的代码是'spinlock'的典型代码。代码循环直到值发生变化。它经常用于数据库中的短期轻量级锁定。即使在CPU上,这也是危险的代码,因为错误或错误可能会锁定CPU或GPU。对于CPU代码,自旋锁通常由中断计时器保护。 用法是

1)设置计时器 2)旋转直到值发生变化 3)继续或超时

因此,在必需的ms数后,代码被中断并引发错误。因此,如果您使用自旋锁模式,为了安全起见,在完成适当数量的循环后,在while语句中添加一个循环出口。

在OpenCL减少算法中,它的典型零线程(get_global_id(0)== 0) 返回最终的单例结果。在此之前,所有线程都将使用屏障调用进行同步

__kernel
void  mytask( ...  , global float * result )
{
    int thread = get_global_id(0);

    ...  your code

    barrier( CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE ) // flush  global and local  variables or enqueue a memory fence see OpenCL spec for details


    if ( thread == 0)  //  Zero thread
      result[0] =  value;  //  set the singleton result as the zeroth array element

}