OpenCL 标准定义了以下选项来获取有关设备和编译内核的信息:
CL_DEVICE_MAX_COMPUTE_UNITS
CL_DEVICE_MAX_WORK_GROUP_SIZE
CL_KERNEL_WORK_GROUP_SIZE
CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE
给定这个值,我如何计算工作组的最佳大小和工作组的数量?
OpenCL 标准定义了以下选项来获取有关设备和编译内核的信息:
CL_DEVICE_MAX_COMPUTE_UNITS
CL_DEVICE_MAX_WORK_GROUP_SIZE
CL_KERNEL_WORK_GROUP_SIZE
CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE
给定这个值,我如何计算工作组的最佳大小和工作组的数量?
您通过实验为您的算法发现这些值。使用分析器获取硬数字。
我喜欢使用 CL_DEVICE_MAX_COMPUTE_UNITS 作为工作组的数量,因为我经常依赖于同步工作项。我通常运行几乎没有分支的内核,因此在每个计算单元中执行的时间相同。
某些倍数的 CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 将最适合您的设备。这个倍数实际上取决于您的内存访问模式和您对每个工作项所做的工作类型。当您运行繁重的计算密集型 (ALU) 内核时,请使用 1 作为倍数。如果您受到内存访问的限制,请尝试使用更大的倍数来隐藏内存延迟。使用分析器来确定您的访问时间和 ALU 时间何时是最佳的。
对于任何设备,ALU 获取的最佳比率是 1:1。这在实践中很少实现,因此您希望保持 ALU/SIMD 组饱和。这意味着 ALU:fetch 应尽可能大于 1。小于 1 意味着您应该尝试更大的工作组大小以更好地隐藏内存延迟。
正如 mfa 所说,您必须通过实验来发现这些。我想补充一点,这取决于您正在计算的内容(特别是作业的大小,即每个工作项的大小),有时一个好的尝试可以是:
也就是说,基本上检查基本情况并弄清楚它如何影响处理管道。
本质上,您必须对其进行调整。我经常针对不同的参数执行多次(分析它),然后生成一个曲面图以查看它的行为。