2011-08-31 171 views
28

是否有任何研究将OpenCL与OpenMP性能进行比较?具体来说,我感兴趣的是使用OpenCL启动线程的开销成本,例如,如果将域分解成大量单个工作项(每个线程执行一项小工作)与OpenMP中较重的线程分别为该域被分解成数量等于核心数量的子域。OpenCL vs OpenMP性能

看来,OpenCL的编程模型更有针对性的向具有更少但功能更强大核心大规模并行芯片(GPU的,例如),而不是CPU的。

OpenCL能否成为OpenMP的有效替代品?

+1

我也很想知道是否/何时一起使用OpenMP和OpenCL是有效的。 OpenCL是线程安全的(除了clSetKernelArg()方法),所以看起来好像还有空间可以利用这两种技术。 –

+0

如果你对“有效”的定义包括可读性和进化性,那么答案必须是“否”。不能像OpenMP那样将OpenCL固定在现有代码上,并且与OpenMP相比,OpenCL具有大量的语法膨胀。另一方面,编写有效利用内存层次结构的OpenMP代码通常比OpenCL中的代码更不可读。 – Jeff

+0

你的问题需要缩小一点。您是否在寻找GPU与多线程CPU,OpenMP与OpenCL的比较?为了比较两种语言,他们确实需要在同一架构上运行。否则,它是苹果和橘子。 – orodbhen

回答

24

我见过的基准测试表明,OpenCL和OpenMP的在同一硬件上运行,通常可比的性能,或OpenMP的具有表现略好。但是,我还没有看到任何我认为是确定性的基准,因为他们大多缺乏对其方法的详细解释。但是,有几件有用的事情需要考虑:

  • 在运行时编译内核时,OpenCL总会有一些额外的开销。任何基准测试都需要单独列出这些时间,使用预编译的本机内核,或者运行足够长的内核编译是微不足道的。

  • OpenCL的实施方式将发生变化。像NVidia这样的GPU供应商没有动力来确保他们的基于CPU的OpenCL实施尽可能快。没有一个OpenCL实现可能像一个好的OpenMP实现那样成熟。

  • OpenCL规范基本上没有提到基于CPU的实现如何在引擎下使用线程,所以关于线程是相对轻量还是重量级的任何讨论都必须是特定于实现的。

  • 当你在CPU上运行的OpenCL代码,你的工作项目不必是微小的和无数。您可以按照与OpenMP相同的方式来分解问题。

即使OpenCL有更多的开销,也可能有其他原因偏好它。

  • 很明显,如果你的代码可以很好地利用GPU,你会想要一个OpenCL实现。 CPU上的OpenCL性能可能已经足够好,因此对于没有强大GPU的用户来说,维护OpenMP后备代码路径也是不值得的。

  • 良好的基于​​CPU的OpenCL实现意味着您将自动获得任何指令集扩展的利益,CPU和OpenCL实现支持。使用OpenMP,您必须做额外的工作来确保您的可执行文件包含SSEx和AVX代码路径。

  • 的OpenCL,基矢量可以帮助你表达不便携性和可读性的牺牲你使用SSE内部函数得到一些明确的并行性。

+0

我想知道用户无GPU的情况是否真的如此。由于CPU不支持2D本地工作大小,存在__本地内存问题等等,而不是维护OpenMP后备代码,您必须维护OpenCL后备代码。如果您已经优化了GPU内核,那么在那里没有太多收获。 –

+2

为什么你认为基于CPU的实现不能支持2D本地工作组大小或本地内存?在CPU上,高速缓存由硬件而不是软件管理,因此全局和本地内存之间唯一的区别在于是否需要使用锁定来访问它。工作组大小将相当于NUMA系统的调度程序提示。是的,为了使它在GPU上运行良好而投入OpenCL代码的很多优化工作不会影响CPU的性能,但它也不会破坏代码。任何将在GPU上运行的内核都可以在兼容的CPU实施上运行。 – user57368

+0

@ user57368:此外,优化的使用(如显式使用本地内存对GPU有意义)。在CPU上,如果对x86 CPU采用英特尔OpenCL实现,则至少有这种优化“可能会负面”影响性能。 – usman

6

我有一个程序可以选择在某些关键瓶颈上使用openCL或openMP,基本上增加了向量和执行减少。

在我的情况下,openMP需要13秒,其中openCL在CPU上需要10秒。英特尔I5。

到目前为止,我的最快配置是使用openCL GPU添加矢量,并在openMP上缩小到7秒。当我在GPU上对openCL内核进行缩减时,总共需要8秒。

所以根据我的经验,我会说可能它取决于使用,并且你可以优化你的openCL内核。

+0

你在这里意味着什么,完全是由“减少”? – nbro

+0

@nbro“减少”是指当你需要大量的元素(比如10,000长度的数组,a [0]到[9999]),然后将数据处理到更小的元素。例如:计算出数组中的“最大”数字或a [0] + a [1] + a [2] + ... a [9999]的值。最常见的减少是“最大”,“最小”和“添加”,但是并行处理大量和大量数据以输出单个数字(或者至少是少数代表整个数字)的概念是并行编程中常见的“模式”。 – Dragontamer5788