我正在使用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};
所以这是我的问题:
为什么没有get_local_id()的代码也会受到本地内存的影响?
如何设置最佳本地尺寸以使其以最高速度运行?
我还测试了其他平台上的运行速度,例如飞思卡尔的IMX.6,似乎改变大小的本地工作大小根本不起作用!那为什么呢?
如果有人知道答案,请帮忙。 非常感谢!
答案 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)
get_local_id()
根本不会影响性能。它只是一个工具,可以在内核中获取工作ID,允许在组内部执行一些同步任务。NULL