为什么我尝试进行全局同步无效?

时间:2019-06-29 07:26:29

标签: opencl

我尝试使用此代码。 但是内核仅在执行一次循环后退出。

如果我删除“ 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
    }
}

1 个答案:

答案 0 :(得分:4)

您似乎希望所有工作组都计划并行运行。 OpenCL不保证会发生这种情况。在其他工作组完全完成内核运行之前,某些工作组可能无法启动。

此外,障碍仅在工作组内同步 。就其他工作组而言,对全局内存的原子操作也是原子的,但是不能保证顺序。

如果在运行其他代码之前需要其他工作组完成一些代码,则需要将每个工作块分别放入串行命令队列中(或使用乱序事件适当地连接它们)队列)。因此,对于您的示例代码,您需要删除forwhile循环,并将内核MAX-1排入队列并传递i作为内核参数。

根据设备的功能和数据集的大小,您的另一种选择是仅提交一个大型工作组,尽管除非您有很多此类较小的任务,否则这不可能给您带来良好的性能彼此独立。

(我要指出的是,您的问题很有可能遭受the XY problem的困扰-您尚未说明代码试图解决的总体问题。因此,可能有比我建议的解决方案更好的解决方案)