调整全局昏暗和局部(块)暗淡的工作的最佳方法

时间:2015-08-10 20:29:03

标签: opencl gpgpu nvidia

我正在尝试在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倍。我想看看如何计算运行内核的最佳值。当然,你的经历会有很大的帮助。

1 个答案:

答案 0 :(得分:1)

为了自动调整全局和本地工作大小,您应首先查询内核对象和/或您的设备以获取以下信息:

有用的内核信息(使用clGetKernelWorkGroupInfo()函数):

  • CL_KERNEL_WORK_GROUP_SIZE:可用于在特定设备上执行内核的最大块大小。
  • CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE:获取块大小的首选倍数。这是一个性能提示,可能是优化全球和本地工作规模的最重要信息。

如果在确定全局和本地工作大小时尚未创建内核对象,则可以使用clGetDeviceInfo()函数查询设备以获取类似信息:

  • CL_DEVICE_MAX_WORK_ITEM_SIZES:可以在块的每个维度中指定的最大线程数。
  • CL_DEVICE_MAX_WORK_GROUP_SIZE:块中的最大线程数。

从您要处理的工作的实际大小(即num_seeding_points)开始,并使用上述功能提供的信息,您可以针对任何OpenCL设备优化全局和本地工作大小使用。最重要的是,始终尝试使本地工作大小为CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE的倍数。

请注意,对于较小的全局大小(低于128或256),您不会看到这些优化带来的好处。

我为名为ccl_kernel_suggest_worksizes()的{​​{3}}库编写了一个函数,根据您要处理的工作大小,设备和可选的内核对象,建议最佳的全局和本地工作大小。检查其源代码cf4ocl,也许它会提供一些额外的提示。