我正在尝试为 NVIDIA GeForce 9800 GT 显卡优化 OpenCL 矩阵乘法程序。我将两个 512x512 矩阵相乘,但我不确定我应该使用什么样的全局和本地工作组大小。谁能指出我正确的方向?
3 回答
作为二512
的幂,您可以尝试以下尺寸:
size_t global_work_size[2] = {512, 512};
size_t local_work_size[2] = {2^p, 2^n};
在哪里 :
(2^m + 2^n) % 32 = 0
:32
必须是线程数的除数,因为包裹将包含线程32
需要 2的幂,因为本地工作大小必须是全局工作大小的除数。
大小为
512
,当然不会有问题,但您必须考虑CL_DEVICE_MAX_WORK_GROUP_SIZE
(由 给出clGetDeviceInfo()
)参数。对于更大的矩阵,您将不得不使用更多的2
维度。维数本身受
CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS
...限制
实际上,最佳选择取决于算法,并且取决于您打算执行的矩阵乘法类型。
如果您需要最佳性能,请使用各种本地工作组规模对其进行基准测试,然后使用最好的一个。您可能会惊讶地发现,最快的并不总是与实现提供者提供的指导相匹配!
同意 Dithermaster,我想补充一点,峰值性能高度依赖于平台,如果 GPU 不是同一型号/代,即使来自同一供应商的 GPU 也可能具有不同的最佳工作组大小。
要获得最佳性能,您确实需要在目标平台上进行实验(执行前训练)并找到最佳配置。请记住,不仅工作组的规模,而且工作组的形状都会显着影响绩效。话虽如此,您确实需要尝试以下所有组合。假设内核的最大工作组大小为 1024,这意味着对于二维工作组,您可以有以下组合:(1, 1024), (2, 512), (4, 256), (8, 128), (16, 64), (32, 32), (64, 16), (128, 8), (256, 4), (512, 2) 和 (1024, 1)。
注意 (1, 1024) 和 (1024, 1) 可能会导致完全不同的性能,这是由于内存架构、缓存架构和波形调度方式等原因。
是的,当然,您还需要考虑 wave/warp 大小以及合并的内存访问。在这里,我只是在谈论一般的 OpenCL 工作负载,尤其是当工作负载不显示任何结构模式时,最好尝试尽可能多的组合以确保您不会遗漏任何内容。