__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内核中的其他线程?
提前致谢!
答案 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
}