我正在尝试在gpu上运行内核。我正在寻找调整线程网格的全局和局部维度的最佳方法。在我的实验中,我理解由1个线程组成的32个块线程比32个线程的1个块(在我的nvidia GTX 980上)快32倍。之前,我使用以下方法确定内核网格尺寸:
size_t local_ws = 32;
size_t nKernels = num_seeding_points;
local_ws = local_ws > nKernels ? nKernels : local_ws;
size_t global_ws = (nKernels + local_ws - 1) / local_ws * local_ws;
但是我知道如果内核的数量不大,这种方式将不会完全使用我的GPU,我们将这部分更改为:
size_t local_ws = 1;
size_t nKernels = num_seeding_points;
local_ws = local_ws > nKernels ? nKernels : local_ws;
size_t global_ws = (nKernels + local_ws - 1) / local_ws * local_ws;
我的代码运行速度比以前快20倍。我想看看如何计算运行内核的最佳值。当然,你的经历会有很大的帮助。
答案 0 :(得分:1)
为了自动调整全局和本地工作大小,您应首先查询内核对象和/或您的设备以获取以下信息:
有用的内核信息(使用clGetKernelWorkGroupInfo()
函数):
如果在确定全局和本地工作大小时尚未创建内核对象,则可以使用clGetDeviceInfo()
函数查询设备以获取类似信息:
从您要处理的工作的实际大小(即num_seeding_points
)开始,并使用上述功能提供的信息,您可以针对任何OpenCL设备优化全局和本地工作大小使用。最重要的是,始终尝试使本地工作大小为CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE的倍数。
请注意,对于较小的全局大小(低于128或256),您不会看到这些优化带来的好处。
我为名为ccl_kernel_suggest_worksizes()
的{{3}}库编写了一个函数,根据您要处理的工作大小,设备和可选的内核对象,建议最佳的全局和本地工作大小。检查其源代码cf4ocl,也许它会提供一些额外的提示。