理想的全球/本地工作组规模(OpenCL)

理想的全球/本地工作组规模(OpenCL),opencl,gpgpu,matrix-multiplication,Opencl,Gpgpu,Matrix Multiplication,我正在尝试为NVIDIA GeForce 9800 GT图形卡优化OpenCL矩阵乘法程序。我将两个512x512矩阵相乘,但我不确定应该使用什么样的全局和本地工作组大小。有人能给我指出正确的方向吗?由于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线程

我正在尝试为NVIDIA GeForce 9800 GT图形卡优化OpenCL矩阵乘法程序。我将两个512x512矩阵相乘,但我不确定应该使用什么样的全局和本地工作组大小。有人能给我指出正确的方向吗?

由于
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
    线程

  • 需要两个的,因为本地工作规模必须是全局工作规模的分割者

  • 如果大小为
    512
    ,当然不会有问题,但您必须考虑
    CL\u设备\u最大工作\u组\u大小
    (由
    clGetDeviceInfo()
    参数给出)。对于较大的矩阵,您将必须使用多于2个维度

  • 尺寸的数量本身受
    CL\u设备\u最大工作\u项目\u尺寸的限制


事实上,最佳选择取决于算法,并取决于您打算执行的矩阵乘法的类型。

如果您需要最高性能,请使用各种本地工作组大小对其进行基准测试,然后使用最佳的。您可能会惊讶地发现,最快的并不总是与实现提供者提供的指导相匹配的

同意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的调度方式等等


当然,你还需要考虑波/经大小以及合并内存访问。在这里,我只是在谈论一个通用的OpenCL工作负载,特别是当工作负载没有显示任何结构模式时,最好使用尽可能多的组合进行实验,以确保不会遗漏任何内容

理想情况下,全局大小应尽可能高,只要您不需要中断计算来添加或修改输入,如果是这样,则使用所需的最大全局大小不会产生递减回报。尽管在实践中,如果您使用的是GPU,大多数GPU还不支持任务并发,所以运行内核的GPU只能做到这一点。因此,如果您将其用作主图形卡,您的屏幕将冻结。至于本地工作大小,它取决于内核和设备,您可以让OpenCL尝试并优化它(查找clGetKernelWorkGroupInfo)。请记住,Nvidia GPU将线程分组为32个线程(一个扭曲),因此用于合并内存访问,您希望本地工作组大小的一个维度是32.0的倍数。事实上,通常最快的大小不是最大大小(基于寄存器文件大小),所以像(8,16),(32,4)这样的大小以及宽度*高度的所有其他大小