在不同计算机上实现 OpenCL 的最佳性能



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

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

谢谢

我与

供应商无关的 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 空闲。

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

最新更新