1

由于 OpenCL 程序在多台机器上运行,每台机器都有其特定的架构,所以我想到了一个问题,即我应该如何编写我的程序才能在这些机器上获得最佳的平均性能。

我很高兴听到你的建议:)

谢谢

4

1 回答 1

7

我的与供应商无关的 OpenCL 优化建议,按顺序:

内存访问

  1. 虽然 GPU 中的内存带宽非常惊人,但它通常是许多内核中最大的瓶颈。因此,尽量减少内存读取和写入。不要读取任何可以存储在变量中的内容两次。
  2. 与 (1) 相关,使相邻的内核访问相邻的内存位置,以便 GPU 可以将访问合并为单个(通常为 128 位或更宽)读取或写入。一般来说,较窄的访问更喜欢宽访问(例如,如果您有一个包含四个单字节元素的数据结构,则将其作为单个 uchar4 读取,而不是执行四个 uchar 读取)。
  3. 如果您的全局数据在多个工作项中使用相同的值,请使用共享本地内存,这样您只需从全局内存中读取一次。共享本地内存的访问速度要快得多。
  4. 如果可以的话,交错内存和计算,而不是先做一个然后再做另一个。GPU 与这些重叠,因此其中一个变得“免费”。

计算

  1. 使用浮点数而不是双精度数。他们要快得多。
  2. 如果您可以容忍较低的精度,请使用 native_ 函数,因为它们通常更快。
  3. 提供足够的工作项以保持 GPU 忙碌。全局工作规模至少应为数千个项目,但数万个或更多更好。任何低于 1000 的值都会使内核闲置。
  4. 避免分支。如果工作组中的工作项具有不同的分支,GPU 将不得不采用两条路径并使用谓词来屏蔽非活动侧的写入。在工作组内一致的分支不是问题。
  5. 避免巨大的内核。大多数编译器内联所有函数调用。GPU 的共享寄存器存储量有限,因此使用大量寄存器的内核可以限制运行中工作组的数量。

主机端

  1. 您提到了程序,但另一个重要方面是将数据输入和输出 GPU。许多 GPU 可以在计算的同时执行此操作,但您需要使用单独的命令队列和事件来确保在需要时一切就绪。它具有挑战性,但可以将串行上传/计算/下载周期转变为并行周期(C 的上传、B 的计算和 A 的下载都同时发生)。
  2. 如果数据传输是您花费时间的重要组成部分,请研究固定内存、零拷贝传输和特定于供应商的内存缓冲区创建标志,它们可以在这里提供帮助。
  3. 尽可能避免 clFinish 和阻塞读/写,以防止命令队列为空,然后 GPU 空闲。

祝你好运,玩得开心,并在你的目标硬件上进行基准测试,以确保你的优化在所有硬件上都是积极的,而不是在某些硬件上倒退。

于 2013-11-10T00:14:22.747 回答