Opencl 如何使用并行运行的多个工作项调用单个工作组?

Opencl 如何使用并行运行的多个工作项调用单个工作组?,opencl,Opencl,我在一家OpenCl初创公司,还在学习 内核代码: __kernel void gpu_kernel(__global float* data) { printf("workitem %d invoked\n", get_global_id(0)); int x = 0; if (get_global_id(0) == 1) { while (x < 1) { x = 0; } } printf

我在一家OpenCl初创公司,还在学习

内核代码:

__kernel void gpu_kernel(__global float* data)
{
    printf("workitem %d invoked\n", get_global_id(0));
    int x = 0;
    if (get_global_id(0) == 1) {
        while (x < 1) {
            x = 0;
        }
    }
    printf("workitem %d completed\n", get_global_id(0));
}
输出:

workitem 3 invoked
workitem 3 completed
workitem 0 invoked
workitem 0 completed
workitem 1 invoked
workitem 2 invoked
workitem 2 completed

## Here code is waiting on terminal for Workitem #1 to finish, which will never end
workitem 0 invoked
workitem 0 completed
workitem 1 invoked
## Here code is waiting on terminal for Workitem #1 to finish, which will never end
这清楚地表明,所有工作项都是并行的(但在不同的工作组中)

另一个用于调用内核的C代码(用于1个具有4个工作项的工作组)

输出:

workitem 3 invoked
workitem 3 completed
workitem 0 invoked
workitem 0 completed
workitem 1 invoked
workitem 2 invoked
workitem 2 completed

## Here code is waiting on terminal for Workitem #1 to finish, which will never end
workitem 0 invoked
workitem 0 completed
workitem 1 invoked
## Here code is waiting on terminal for Workitem #1 to finish, which will never end
这清楚地表明,这是按顺序运行的(这就是为什么它完成了第一个工作项,然后卡在第二个工作项上,而其余的工作项从未执行)

我的问题:

我需要用4个并行运行的工作项调用1个工作组。这样我就可以在我的代码中使用屏障(我想这只能在单个工作组中实现)


任何帮助/建议/指针都将不胜感激。

您的第二个主机代码片段将正确启动包含4个工作项的单个工作组。您无法保证这些工作项将并行运行,因为硬件可能没有这样做的资源。但是,它们将同时运行,这正是您能够使用工作组同步结构(如屏障)所需要的。有关并行性和并发性之间区别的简明描述,请参见。基本上,工作组中的工作项将彼此独立地向前推进,即使它们实际上不是并行执行的

OpenCL 1.2规范(第3.2节:执行模型)

给定工作组中的工作项在单个计算单元的处理元素上并发执行

基于您之前关于类似主题的问题,我假设您正在使用AMD针对CPU的OpenCL实现。大多数OpenCLCPU实现的工作方式是将工作组中的所有工作项序列化到单个线程中。然后,该线程依次执行每个工作项(为了参数而忽略矢量化),在它们完成或遇到障碍时在它们之间切换。这就是它们实现并发执行的方式,并为您提供了安全使用内核中的屏障所需的所有保证。并行执行是通过拥有多个工作组来实现的(如第一个示例中所示),这将导致多个线程在多个内核上执行(如果可用)


如果用屏障替换无限循环,您会清楚地看到这确实有效。

谢谢您的回复。你说得对。是的,我正在使用AMD针对CPU的OpenCL实现。我的主要座右铭是只使用屏障。但是,屏障不适用于多个工作组(这是我的第一个示例),我可以在单个工作组具有多个工作项的情况下使用屏障。用屏障替换无限循环清楚地显示了您所说的屏障的使用。但是,它们是“并发”运行的(我可以看到打印语句是以固定顺序的0,1,2,3..因此我假设它是顺序/并发的)如何使它们并行?您也可以建议我查看一些需要检查的系统属性,以确认原因。@Vishwadeep您不能强制单个工作组的工作项并行执行。在某些设备上,它们可能会执行,但规范仅保证它们将并发执行。正如我提到的,在CPU上,这些工作项将被串行化为一个线程,这使它们能够有效地实现屏障(而不是通过内存在不同的内核之间传递屏障状态,这会很慢)。。谢谢另一个小问题。。如果我将GeForce GT 630与设备类型CL\U设备类型\U GPU一起使用。。同样的逻辑是否也适用于它???@Vishwadeep无论设备如何,您拥有的并发保证都是相同的。在这个特定的GPU上,我希望来自同一个工作组的32个工作项的组(在NVIDIA硬件上称为“warps”)将并行执行,而不仅仅是并发执行。