【问题标题】:OpenCL vs OpenMP performance [closed]OpenCL 与 OpenMP 性能 [关闭]
【发布时间】:2011-11-07 22:58:12
【问题描述】:

有没有比较 OpenCL 和 OpenMP 性能的研究?具体来说,我对使用 OpenCL 启动线程的开销成本感兴趣,例如,如果要将域分解为大量单独的工作项(每个工作项由一个执行小工作的线程运行),而 OpenMP 中较重的线程是域被分解为子域,其数量等于核心数。

OpenCL 编程模型似乎更针对大规模并行芯片(例如 GPU),而不是内核更少但功能更强大的 CPU。

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

【问题讨论】:

  • 我也很想知道同时使用 OpenMP 和 OpenCL 是否/何时有效。 OpenCL 是线程安全的(clSetKernelArg() 方法除外),因此似乎有可能利用这两种技术。
  • 如果您对“有效”的定义包括可读性和进化性,那么答案必须是“否”。 OpenCL 不能像 OpenMP 那样被固定到现有代码上,而且与 OpenMP 相比,它有大量的语法膨胀。另一方面,编写能够有效利用内存层次结构的 OpenMP 代码通常比在 OpenCL 中的可读性要低得多。
  • 我可以在这里找到 OpenMP 和 OpenCL 之间的良好和科学比较:Comparison of OpenMP & OpenCL Parallel Processing Technologies,作者 Krishnahari Thouti 和 S.R.Sathe
  • 您的问题需要缩小一点。您是否正在寻找 GPU 与多线程 CPU 或 OpenMP 与 OpenCL 的比较?要比较这两种语言,它们确实需要在相同的架构上运行。否则,就是苹果和橙子。

标签: opencl gpgpu


【解决方案1】:

我有一个程序可以选择在一些关键瓶颈上使用 openCL 或 openMP,基本上是添加向量并执行缩减。

在 CPU 上,openMP 需要 13 秒,而 openCL 需要 10 秒。英特尔 I5。

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

所以根据我的经验,我会说这可能取决于使用情况,您可以优化您的 openCL 内核。

【讨论】:

  • 这里的“减少”是什么意思?
  • @nbro “缩减”是指您获取大量元素(例如一个 10,000 长度的数组,a[0] 到 a[9999]),然后将数据处理为较小的元素。例如:找出数组中的“最大”数,或者 a[0] + a[1] + a[2] + ... a[9999] 的值。最常见的缩减是“Max”、“Min”和“Add”,但并行处理大量数据以输出单个数字(或至少:更少的数字代表整体)的概念是并行编程中的常见“模式”。
【解决方案2】:

我看到的基准测试表明,在相同硬件上运行的 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 内在函数而牺牲可移植性和可读性。

【讨论】:

  • 我想知道没有 GPU 的用户案例是否真的那么实用。您必须维护 OpenCL 后备代码,而不是维护 OpenMP 后备代码,因为 CPU 不支持 2D 本地工作大小,__local 内存存在问题等等。如果您优化了 GPU 内核,则不会有太大收获。
  • 为什么您认为基于 CPU 的实现不能支持 2D 本地工作组大小或本地内存?在 CPU 上,高速缓存由硬件而不是软件管理,因此全局内存和本地内存之间的唯一区别在于是否需要锁定才能访问它。工作组大小相当于 NUMA 系统的调度程序提示。是的,为使其在 GPU 上良好运行而对 OpenCL 代码进行的大量优化工作不会影响 CPU 的性能,但也不会破坏代码。任何将在 GPU 上运行的内核都可以在兼容的 CPU 实现上运行。
  • @user57368:只是补充一点,使用优化(例如显式使用本地内存)对 GPU 有意义。在 CPU 上,进行这种优化“可能会对性能产生负面影响”,至少在为 x86 CPU 使用 Intel OpenCL 实现时是这样。
  • @user57368:也许英特尔 SDK 就是这样工作的。苹果没有。我的 Core2Duo 在 Mac OS 10.6 下的 CL_DEVICE_MAX_WORK_ITEM_SIZES 是 {1,1,1},在 10.7 下至少是 {1024,1,1},但仍然不是 2D。此外,任何具有多个局部变量的内核都会使编译器在 10.6 下放弃 - 我称之为破坏代码。
  • @w.m 您可以针对 CPU 优化 OpenCL 代码,而不使用本地内存等 - 性能与 OpenMP 相当。由于内核通常很小,如果系统有可用的 GPU,您仍然可以共享主机代码并使用它来获得更高的性能,只切换内核(为 GPU 优化的内核)并且作为工作组大小的参数很少。这说明不保留后备代码 - 很大一部分在主机代码中,并且是共享的。
猜你喜欢
  • 2014-06-15
  • 2017-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 2012-02-16
  • 2012-10-06
  • 1970-01-01
相关资源
最近更新 更多