繁体   English   中英

OpenCL与Grand Central Dispatch的并发编程

[英]Concurrent programming in OpenCL vs Grand Central Dispatch

随着OpenCL 2.0的推出,OpenCL似乎具有Grand Central Dispatch(GCD)的许多功能,例如CLang / Apple风格的块和队列。 看看他们各自的功能集,我想知道OpenCL是否可以完成GCD / libdispatch可以做的所有事情,但是增加了将计算引导到GPU以及CPU的能力 - 或者如果GCD有更多的功能可以分开来自OpenCL。

具体来说我的问题是:

  1. GCD和OpenCL的并发功能有何区别?

  2. 如果将它们一起使用有价值(假设GCD提供了附加功能),C块可以路由到GCD队列还是OpenCL队列? 如果针对CPU,是否有理由通过OpenCL直接运行

  3. OpenCL 2.0是否提供GCD样式的负载平衡,可以填充跨越CPU和GPU的线程?

在目前的形式中,OpenCL能够解决数据并行和任务并行问题,正如用于排队工作的不同OpenCL API原语所证明的那样:

  • clEnqueuNDRangeKernel :用于将具有N维工作组大小的内核排入队列。 通常用于数据并行处理。
  • clEnqueueTask :用于将包含单个工作项的内核排入队列。 这个用于任务并行执行的原语实际上等同于clEnqueueNDRangeKernel ,其全局工作大小为1.它已从OpenCL 2.0规范中删除
  • clEnqueueNativeKernel将本机C / C ++函数排入设备(如果它支持本机内核),好处是您可以使用排队机制(以及队列中的排序)并直接从OpenCL上下文访问缓冲区数据。 除此之外,这与线程或任务的概念非常相似。

因此,虽然OpenCL明显起源于GPU上的数据并行处理,并且仍然最适合处理可以某种方式强制在1,2或3维网格中的数据,但是面向任务的处理也是可能的。 一旦开始针对具有多个CPU,GPU,DSP和加速器的异构系统,其优势就会变得更加明显,因为OpenCL可以通过一种形式将所有这些设备作为目标。

另一方面,GCD提供了一个方便的库,通过构建队列(不同类型和优先级)的概念,使开发人员免于管理和调度任务的大部分负担。 因此,使用GCD可以在对称多处理系统上产生更少的错误和更紧凑的代码。

因此,尽管OpenCL和GCD在其起源上具有不同的背景(除了它们都来自Apple),它们都在其基础上使用队列来管理工作项分发。 它们都有一个“上下文”的概念来定义数据访问。

从OS X版本10.7开始,可以使用GCD将OpenCL内核(类似于块)分派给支持OpenCL的设备,从而开启了结合OpenCL和GCD的优势/优势的潜力。

以下是针对您的具体问题的一些答案/见解的尝试:

1 - GCD和OpenCL的并发特性有何区别?

正如@Dithermaster和@sharpneli所指出的,GCD最初的目标是面向任务的(对称多)处理,而OpenCL最初用于异构架构上的数据并行处理。

OpenCL和GCD之间的一个主要区别在于排队机制。 例如,虽然OpenCL和GCD都支持同步和异步执行,但GCD有三个全局异步队列的优先级。 OpenCL运行时没有这个(它没有工作项的无序执行,但是没有定义运行时首先执行哪些工作项)。

GCD手册还指出任务比传统线程更轻量级,使得生成GCD任务的指令比线程少得多。

另一个区别在于使用的内存一致性模型。 OpenCL使用松散的内核模型,具有全局,本地,私有和常量内存。 GCD没有这个。

另一方面,OpenCL具有矢量数据类型和矢量内在函数,允许直接利用架构的SIMD潜力而不依赖于编译器。 在某些体系结构上,这是有益的,而其他体系结构(如MIC)建议不要手动进行矢量化。

最后 - 虽然不是真正的并发功能 - OpenCL具有允许读写图像类型的功能,实质上可以让您直接访问纹理内存。 即使对于与图像处理无关的算法,这通常也可用于获得显着的加速。

2 - 如果将它们一起使用有价值(假设GCD提供了附加功能),C块可以路由到GCD队列还是OpenCL队列? 如果针对CPU,是否有理由通过OpenCL直接运行

通过一起使用GCD和OpenCL,您可以解决任何支持OpenCL的设备。 因此,您可以使用平台的潜在异构特性,同时仍然可以从GCD提供的更高级别机制中受益,从而使多线程更容易。 使用OpenCL C API(甚至是C ++ API)编写所有内容可能会导致更多的代码。

此外,GCD提供了诸如gcl_get_kernel_block_workgroup_info原语,可以为内核推荐最佳工作组大小。

但是,根据我的理解,不可能将任意C块路由到GCD或OpenCL队列。 C块只能进入非OpenCL队列。 OpenCL内核只能(从主机端)调度到支持OpenCL的设备的队列。 从设备端(因此在OpenCL内核中),块只能被分派到同一设备。

3 - OpenCL 2.0是否提供GCD样式的负载平衡,可以填充跨越CPU和GPU的线程?

不,OpenCL 2.0并没有真正定义如何进行负载平衡,无论是从主机的角度还是从设备的角度来看。

但是,在主机端,可以轻松地分离计算并在CPU上运行部分计算,在一个或多个GPU上运行另一部分。 一种方法是使用工作组大小和工作组偏移量,只复制每个设备所需的最小数据。 然后可以使用自动调整机制来确定所使用的不同设备之间的最佳负载平衡。

一旦OpenCL 2.0驱动程序可用,新引入的管道,动态并行和共享虚拟内存将为在设备之间有效分区工作提供更多可能性。 目前尚不清楚这些功能是否以及如何通过GCD获得。

1)Dithermaster已经很好地回答了。 OpenCL适用于您的问题并行化很好并且您拥有大量数据的情况。 GCD适用于必须毫不费力地生成线程来处理文件IO或诸如此类的东西。 您永远不能从OpenCL调用任何系统或其他库函数。

2)如果您的问题很容易并行化,那么即使在CPU上使用OpenCL也是值得的。 作为示例,英特尔的OpenCL实现设法水平并行化一些内核,以便单个核心有效地同时运行8个线程(一个线程在SSE寄存器的一个向量组件中“运行”)。

您不能将通用C块传递给OpenCL。 只是内核本身而已。 OpenCL对你可以执行的内容更加挑剔。 新奇的Clang IR带来的唯一功能就是能够避免以文本形式分发内核源代码。 它仍然仅限于OpenCL内核代码。

3)不自动。 确实存在执行此操作的一些实现。 去年,GDC Intel在其CPU上展示了自动负载平衡(它同时使用了集成的GPU和CPU)。

OpenCL2.0并不关心它运行的硬件类型,因此硬件制造商有责任在其平台上实现此类功能。 或者对于不相交的平台,这是程序员头痛的问题。

“OpenCL具有矢量数据类型和矢量内在函数,允许直接利用架构的SIMD潜力而不依赖于编译器” - Erik Duymelinck

Apple确实推出了iOS 8和OS X Yosemite

  • 2D,3D,4D矢量马赫和几何。
  • CPU上的C,Obj-C和C ++中的金属特征
  • 特定于体系结构的SIMD以及类型和内在函数的抽象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM