我尝试使用此代码。 但是内核仅在执行一次循环后退出。
如果我删除“ while(...)”行-循环有效,但结果当然是混乱的。 如果我声明“ volatile __global uint * g_barrier”,它将冻结黑屏的PC一段时间,然后编程死锁。
__kernel void Some_Kernel(__global uint *g_barrier)
{
uint i, t;
for (i = 1; i < MAX; i++) {
// some useful code here
barrier(CLK_GLOBAL_MEM_FENCE);
if (get_local_id(0) == 0) atomic_add(g_barrier, 1);
t = i*get_num_groups(0);
while(*g_barrier < t); // try to sync it all
}
}
答案 0 :(得分:4)
您似乎希望所有工作组都计划并行运行。 OpenCL不保证会发生这种情况。在其他工作组完全完成内核运行之前,某些工作组可能无法启动。
此外,障碍仅在工作组内同步 。就其他工作组而言,对全局内存的原子操作也是原子的,但是不能保证顺序。
如果在运行其他代码之前需要其他工作组完成一些代码,则需要将每个工作块分别放入串行命令队列中(或使用乱序事件适当地连接它们)队列)。因此,对于您的示例代码,您需要删除for
和while
循环,并将内核MAX-1
排入队列并传递i
作为内核参数。
根据设备的功能和数据集的大小,您的另一种选择是仅提交一个大型工作组,尽管除非您有很多此类较小的任务,否则这不可能给您带来良好的性能彼此独立。
(我要指出的是,您的问题很有可能遭受the XY problem的困扰-您尚未说明代码试图解决的总体问题。因此,可能有比我建议的解决方案更好的解决方案)