在内核中序列化工作组项

时间:2014-10-12 21:58:33

标签: opencl

我有一个执行两个任务的内核,A后跟B.

A在所有工作项上并行化,B是非常顺序的,所以只是 第一个工作项执行它。

如果我能按顺序执行它们,每个工作项都可以执行B的一部分。 这是一个2D内核,我想让工作项以光栅模式执行。

这可能吗?一个想法是所有工作项都可以读取的局部变量,以及唯一的 与变量匹配的工作项将执行并修改变量,以便触发下一个要执行的工作项。

关于如何做到这一点的任何想法/模式?

谢谢!

编辑:

以下是我的内核当前工作方式的一些伪代码:

void myKernel(void) {

    // perform A task (all work items are active)

    barrier(CLK_LOCAL_MEMORY_FENCE);

   if (get_local_id(0) == 0 && get_local_id(1) == 0) {
      //perform task B
  }

}

以下是我希望它如何工作:

// 10 x 10 2D kernel
void myKernel(void) {

    // perform A task (all work items are active)

    barrier(CLK_LOCAL_MEMORY_FENCE);

    local activeIndex =0;
    while (activeIndex < 100) {
        if ( get_local_id(0) + 10* get_local_id(1) == activeIndex) {
             // perform part of task B
             activeIndex++;
        } 
        barrier(CLK_LOCAL_MEMORY_FENCE);
    }
  }
}

编辑2:我在HD 7700上尝试了这个代码,但速度非常慢。我想我会坚持使用本地记忆。

2 个答案:

答案 0 :(得分:0)

您无法保证所有&#34; A&#34;工作项目将一起运行;他们可以分批运行。所以你不能做&#34; B&#34;,即使只有一个工作项,也可以和#34; A&#34;在同一个内核中。如果所有&#34; A&#34;工作项目必须在&#34; B&#34;之前完成。开始,&#34; B&#34;必须是一个单独的内核,你可以运行任何全局工作大小对你的问题最有意义。

答案 1 :(得分:0)

您可以在每个工作组的基础上执行您所描述的内容。障碍将为您提供所需的功能。如果你想在全球范围内这样做,那你就不走运了。在恢复内核之前使用变量来检查全局状态被称为“自旋锁定”,我已经引起了一些WSOD(白屏死机)情况为自己尝试这个。

您发布的示例代码没有任何问题,除非可能缺少参数...

void myKernel(void) {

    // perform A task (all work items are active)

    barrier(CLK_LOCAL_MEMORY_FENCE);

   if (get_local_id(0) == 0 && get_local_id(1) == 0) {
      //perform task B
  }

}