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

在不同的机器上实现OpenCL的最佳性能,opencl,Opencl,由于OpenCL程序在多台机器上运行,每台机器都有其特定的体系结构,因此我想到了这个问题:我应该如何编写程序以在这些机器上获得最佳的平均性能 我很高兴听到你的建议:) 感谢我的与供应商无关的OpenCL优化建议,顺序如下: 内存访问 虽然GPU中的内存带宽是惊人的,但它通常是许多内核中最大的瓶颈。因此,尽量减少内存读取和写入。不要读取任何可能存储在变量中的内容两次 与(1)相关,使相邻的内核访问相邻的内存位置,以便GPU可以将访问合并为单个(通常为128位或更宽)读取或写入。一般来说,更喜欢宽访

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

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


感谢我的与供应商无关的OpenCL优化建议,顺序如下:

内存访问

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

  • 使用float而不是double。他们快得多
  • 如果可以容忍较低的精度,请使用本机函数,因为它们通常更快
  • 提供足够的工作项以保持GPU繁忙。全局工作大小应至少为数千项,但最好为数万项或更多项。任何低于1000的值都将使内核闲置
  • 避免分支。如果工作组中的工作项具有不同的分支,GPU将必须采用两种路径,并使用谓词来屏蔽非活动侧的写操作。在工作组中保持一致的分支不是问题
  • 避免大粒。大多数编译器内联所有函数调用。GPU的共享寄存器存储量有限,因此使用大量寄存器的内核可以限制飞行中工作组的数量
  • 主办方

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

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

    我的供应商不可知OpenCL优化建议,顺序如下:

    内存访问

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

  • 使用float而不是double。他们快得多
  • 如果可以容忍较低的精度,请使用本机函数,因为它们通常更快
  • 提供足够的工作项以保持GPU繁忙。全局工作大小应至少为数千项,但最好为数万项或更多项。任何低于1000的值都将使内核闲置
  • 避免分支。如果工作组中的工作项具有不同的分支,GPU将必须采用两种路径,并使用谓词来屏蔽非活动侧的写操作。在工作组中保持一致的分支不是问题
  • 避免大粒。大多数编译器内联所有函数调用。GPU的共享寄存器存储量有限,因此使用大量寄存器的内核可以限制飞行中工作组的数量
  • 主办方

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

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

    关于内存访问下的第4点,你会遇到一个问题i