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

Ahm*_*osh 1 opencl

由于OpenCL程序在几台具有其特定架构的机器上运行,因此我想到如何编写程序以在这些机器上获得最佳平均性能.

我很乐意听到你的建议:)

谢谢

Dit*_*ter 6

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

内存访问

  1. 虽然GPU中的内存带宽是惊人的,但它通常是许多内核中最大的瓶颈.因此,最小化内存读写.不要读取任何可以存储在变量中的内容.
  2. 与(1)相关,使相邻内核访问相邻的内存位置,以便GPU可以将访问合并为单个(通常是128位或更宽)的读取或写入.通常,优先选择宽访问而不是窄访问(例如,如果您有一个包含四个单字节元素的数据结构,则将其读作单个uchar4而不是执行四个uchar读取).
  3. 如果您拥有在多个工作项中使用相同值的全局数据,请使用共享本地内存,这样您只能从全局内存中读取一次.共享本地内存访问速度要快得多.
  4. 如果可以的话,交错内存和计算,而不是完成所有其他操作,然后完成所有操作.GPU与这些重叠,因此其中一个变得"自由".

计算

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

主持人

  1. 您提到了程序,但另一个重要方面是将数据传入GPU或从GPU中获取数据.许多GPU可以在计算的同时执行此操作,但您需要使用单独的命令队列和事件来确保在需要时准备好所有内容.这很有挑战性,但可以将串行上传/计算/下载周期转换为并行周期(上传C,计算B,同时下载A全部发生).
  2. 如果数据传输是花费时间的一个重要部分,请调查固定内存,零拷贝传输和特定于供应商的内存缓冲区创建标记,这些都可以提供帮助.
  3. 如果可能,请避免clFinish并阻止读/写,以防止命令队列为空,然后GPU空闲.

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