OpenCL,如何为大型计算推广代码?

时间:2015-08-14 04:24:09

标签: opencl

我对OpenCL如何划分大量计算任务感到困惑。我不确定如何正确地提出问题,所以请让我从我认为OpenCL如何工作开始,然后我会根据这个例子问一个具体的问题。以下是我认为它的工作原理:

  • 在内核中加载
  • 设置参数
  • 选择工作项数< - 我的问题将是关于此步骤
  • 然后运行内核。

假设我想使用内核(无论它是什么)来解决给定数量的问题。我手动设置local_item_size,然后设置global_item_size,使其为local_item_size大于number of problems的倍数。像这样:

// Set work item population 
local_item_size = 8;
global_item_size = (number_of_problems / local_item_size + 1) * local_item_size;

// Run
clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_item_size, &local_item_size, 0, NULL, NULL);

所以,如果有number_of_problems = 25,那么global_item_size = 32。这是因为大于8的{​​{1}}的最小倍数是25。好的,很简单,内核运行,我们忽略了一些项目的结果,完成了工作。

现在让我们假设我希望我也这样做,但对于大量的工作项目。举个例子,假设我想为某些大型数组中的每个索引组合运行内核:

32

如果number_of_problems = getCombinations(input); // Set work item population local_item_size = _____; global_item_size = (number_of_problems / local_item_size + 1) * local_item_size; 很大,那么input会非常大 - 你会想到我的想法。我想明白如何明智地选择number_of_problems

最后,我的两部分问题:

1)使用GPU时,OpenCL:

  • a)运行一组工作组,然后运行另一组,依此类推,直到所有工作项完成,或者
  • b)只是尝试一次运行所有工作组?

如果答案是 a ,那么我该如何设置local_item_size 明智地以便尽可能多地使用资源(没有工作组也是如此)大)?

如果答案是 b ,那么我很困惑(我认为OpenCL有一些神奇的功能可以自动拆分工作项)!我应该重新构建内核并运行它多次,相应地改变输入吗?如果这是最好的方法,那么如何选择重建内核的次数明智地

感谢阅读,我期待着解决这个问题!

1 个答案:

答案 0 :(得分:1)

问题的第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:工作组中的最大工作项数。

换句话说,您不能使本地大小大于CL_KERNEL_WORK_GROUP_SIZE或CL_DEVICE_MAX_WORK_GROUP_SIZE,并且本地大小应该是CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE的倍数。无论是否存在大量问题,您都应该使用此信息来确定您的本地大小。

问题的第2部分:

主要取决于工作组的数量(即全球规模除以当地规模)。工作组通常在GPU计算单元(又称流式多处理器或SIMD核心)上执行,因此如果您的GPU具有足够的计算单元,它将以大致同时的方式安排您的工作组,如果没有,它可以处理一些工作组在每一次。

但是,性能方面最重要的方面实际上是本地大小,它决定了计算单元处理完整工作组的速度。每个计算单元都有许多处理元素(a.k.a着色器单元,CUDA核心或SIMD通道),通常可以确定可以同时执行的工作组中的工作项数量。这称为warp size(NVidia)或wavefront(AMD),是CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE返回的值。如果您的本地大小是此值的倍数,您的GPU将能够以最佳方式计划计算单元中的工作项,并尽快处理工作组。

请注意,这是一个简化的解释,但如果您使用CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE提示,则很可能会获得优化的计算。