我是OpenCL的初学者,并尝试使用GPU进行数据集的并行处理。这些数据集的大小不等,范围从10到10000,并且逐个调用这些集合的相同内核。每次调用的问题大小都等于`set_size' 内核代码包含:
int id = get_global_id(0);
result = Process dataset[id]
output[id] = result;
output
是一个全局数组,用于取回结果。
我的GPU有6个计算单位,最大local_group_size
为256.为了公平分配工作项,我使用local_group_size=64
并将全局工作大小设置为:
local_work_groups=set_size / local_group_size;
if (set_size % local_work_size) != 0
local_work_groups++;
global_work_size=local_work_groups*local_group_size;
....
....
clEnqueueNDRangeKernel(command_queue,kernel,1,NULL,&global_work_size,local_group_size,0,NULL,NULL);
本地和全局NDRange只使用一个维度。混淆是如果set_size=120
怎么办?
如果使用local_group_size=64
和global_work_size=128
,那么当线程获得id=121
时会发生什么。输入数据集中没有121th
个元素。它将如何处理output[121]
?
我是否需要声明output[global_work_size]
而不是output[set_size]
并使用额外的随机8数据值填充输入?我可以在不使用条件检查或障碍的情况下在内核中丢弃这8个额外的结果吗?
如果我遗失了,请告知。
答案 0 :(得分:1)
如果您使用opencl&gt; = 2.0,则将NULL作为本地工作组大小将允许实现将工作组拆分为非统一大小(即保持最佳性能而不进行代码修改)。这是由英特尔和AMD支持,但不是nvidia。在opencl <= 1.2下,这将产生不良的性能
如果您在opencl&lt; = 1.2下运行,那么您可以选择填充全局工作缓冲区并忽略额外的计算数据,或者在内核中插入条件检查以消除无效线程。对于中等大小的内核,这通常足够快,不应该是一个问题。