我的同学和我第一次面对OpenCL。正如所料,我们遇到了一些问题。下面我总结了我们遇到的问题和我们找到的答案。但是,我们不确定我们是否做得好,所以如果你们能够看看我们的答案和他们下面的问题,那就太棒了。
为什么我们不把它分成单个问题?
在我看过的OpenCL大部分讲座中,他们使用相同的插图来介绍计算单元和处理元素以及工作组和工作项。这导致我的同学和我不断混淆这些概念。因此,我们现在提出了一个定义,强调处理元素与工作项非常不同的事实:
问题1:这是对的吗?有没有更好的方式表达这个?
这就是我们如何看待 NDRange 的概念:
问题2:再一次,这是正确的吗?
问题3:这些维度只是为了便利吗?可以简单地将图像的每个像素的颜色值存储在大小为width * height
的线性向量中。任何3D问题都是如此。
问题4:我们被告知可以使用barrier(CLK_LOCAL_MEM_FENCE);
Understood在工作组内同步内核的执行(换句话说:工作项)。我们也(反复)被告知工作组无法同步。好的。但那么barrier(CLK_GLOBAL_MEM_FENCE);
的用途是什么?
问题5:在我们的主机程序中,我们指定一个上下文,其中包含来自一个可用平台的一个或多个设备。但是,我们只能将内核排入所谓的命令队列中,该命令队列与一个设备(必须在上下文中)完全链接。同样:命令队列未链接到先前定义的上下文,而是链接到单个设备。正确?
答案 0 :(得分:8)
问题1:差不多正确。工作项是内核的实例(参见标准3.2节的第2段)。另请参阅标准中处理元素的定义:
处理元素:虚拟标量处理器。工作项目可以 在一个或多个处理元素上执行。
另请参阅我提供给question的答案。
问题2& 3:使用多个维度或完全相同数量的工作项,而不是要处理的数据元素取决于您的问题。这取决于您以及开发的简便性。另请注意,您使用ocl 1.2及以下的约束会强制您将全局大小设置为工作组大小的倍数(使用ocl 2.0删除)。
问题4:是的,由于存在障碍,只能在工作组内执行内核期间的同步。作为参数传递的标志之间的区别是指内存的类型。使用CLK_LOCAL_MEM_FENCE,所有工作项必须确保其他人必须能够看到他们必须在本地存储器中写入的数据。使用CLK_GLOBAL_MEM_FENCE时,它与全局内存相同
问题5:在上下文中,您可以让多个设备拥有多个命令队列。如上所述,命令队列链接到一个设备,但您可以将内核排入不同设备的不同命令队列中。请注意,如果两个命令队列尝试访问同一个内存对象(没有同步),则会出现未定义的行为。当各自的作业不相关时,通常使用两个或更多命令队列。
但是,您可以通过事件同步命令队列,事实上您也可以创建自己的事件(称为用户事件),请参阅第5.9节中的事件和第5.10节中的用户事件(标准)。
我建议你至少阅读标准的第一章(1到5)。如果你赶时间,至少第2章实际上是词汇表。