如何设置OpenCL的本地工作空间大小?

时间:2014-04-14 08:46:47

标签: memory kernel local-storage opencl

我正在使用OpenCL进行一些图像处理。

例如,我使用了100 * 200尺寸的图像。在.cl代码中,我只有一半的图像像素值:

{
  int width=get_group_id(0);
  int height=get_group_id(1);

  // col(width)
  int x= get_global_id(0);
  // row(height)
  int y= get_global_id(1);
  (unsigned char) data_output[x*width+y]= 
     (unsigned char)data_input[x*width+y]/2;
}

在内核的参数设置之后,我通过以下方式运行内核:

clEnqueueNDRangeKernel( queue,kernel_DIP,2,NULL,global_work_size,local_work_size, 0,NULL,NULL);

我使用的global_work_size是图像大小:

   size_t global_work_size[2] = {100,200};

我发现即使.cl代码也不包含一些代码,例如“get_local_id(0);”

local_work_size对性能也有很大影响。

这两个 “size_t local_work_size [2] = {1,1};”(小的本地工作量)和“size_t local_work_size [2] = {50,50};” (工作量大)很慢。

如下所示的一些合适尺寸会更快:

size_t local_work_size[2]= {10,10};

所以这是我的问题:

  1. 为什么没有get_local_id()的代码也会受到本地内存的影响?

  2. 如何设置最佳本地尺寸以使其以最高速度运行?

  3. 我还测试了其他平台上的运行速度,例如飞思卡尔的IMX.6,似乎改变大小的本地工作大小根本不起作用!那为什么呢?

  4. 如果有人知道答案,请帮忙。 非常感谢!

2 个答案:

答案 0 :(得分:3)

DarkZeros已经提到过,您可以将本地工作大小设置为null,让OpenCL选择它认为的大小#34;适当的",给定全局工作大小及其设备执行。

但是,对于某些全球工作规模,OpenCL可能无法选择合适的"当地工作规模。特别是当全局工作大小是大于最大本地工作大小的素数时。然后可能会强制使用本地工作大小1.您可以考虑填充您的输入数据,以便它可以很好地分布在几个工作组中。 (我最近在https://stackoverflow.com/a/22969485

中写了几句话

对于复杂的内核,您可以考虑查询CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE并将计算基于此,但对于这个简单的内核,这不是必需的。

此外,您可能想看一下" AMD APP KernelAnalyzer"或者" NVIDIA占用计算器" - 这些工具可能会为某些目标平台提供一些适当配置的提示(尽管最好,代码应尽可能通用,只要它没有太严重的性能影响)

答案 1 :(得分:2)

  1. 本地大小会影响设备的工作方式。代码使用与否get_local_id()根本不会影响性能。它只是一个工具,可以在内核中获取工作ID,允许在组内部执行一些同步任务。
  2. 如果您的代码不需要特定大小(并且不需要)。只需将其设置为默认值,即:NULL
  3. 使用"试错法"随时更改本地尺寸不是要走的路。在某些情况下可能根本不起作用。当地规模必须遵循一些规则:
    • 总局部大小(乘以所有维度)不能高于设备最大本地大小。 (CL_DEVICE_MAX_WORK_GROUP_SIZE)
    • 尺寸不能高于CL_DEVICE_MAX_WORK_ITEM_SIZES中指定的尺寸限制。
    • 本地工作组大小必须是全局大小的整数除数(在所有维度中)。