2017-08-22 36 views
0

我正在处理尺寸为xdim = 49,ydim = 1024和zdim = 64的三维数组。我的DEVICE_MAX_WORK_ITEM_SIZES只有512/512/512。如果我宣布我OpenCL:3D数组处理 - 全局大小限制

size_t global_work_size = {xdim, ydim, zdim};并启动3D内核,

因为我ydim> 512。我得到错误的结果。如果我所有的尺寸都是512以下,我收到了预期的效果。请让我知道这是否有其他选择?

回答

1

CL_DEVICE_MAX_WORK_ITEM_SIZES只限制工作组的大小,而不是全局工作项的大小(是的,这是一个常数的可怕名称)。您受CL_DEVICE_MAX_WORK_GROUP_SIZE严格限制,这是工作组中允许的项目总数(由于乘法因素,您通常比CL_DEVICE_MAX_WORK_ITEM_SIZES快得多)

因此,请继续启动您的全球工作规模49 ,1024,64。它应该工作。如果不是的话,你用get_local_id代替get_global_id还是有一些其它的错误。我们定期推出的2D内核具有4096×4096的全球工作尺寸。

也见Questions about global and local work size

如果你不使用共享本地内存,你不需要担心本地工作组的大小。事实上,哟你可以通过NULL而不是指向local_work_size的一个大小数组的指针,并让运行时选择一些东西(这有助于如果你的全局维度容易被小数除尽)。

1

假设您提供的尺寸是数据的大小,您可以通过让每个GPU线程计算更多数据来减少全局工作量。我的意思是,你案例中的每一个线程都会进行一次计算,如果你改变了你的内核,让我们在y维度上进行2次计算,那么你可以将你发射的线程数减半。 global_work_size决定你正在执行的每个方向有多少个线程。让我举一个例子:

假设你有一个数组,你要做一些计算,你的数组大小是2048.如果你用以下方式编写你的内核,你将需要2048作为在global_work_size:

__kernel void calc (__global int *A, __global int *B) 
{ 
    int i = get_global_id(0); 
    B[i] = A[i] * 5; 
} 

在这种情况下,全局工作尺寸为:

size_t global_work_size = {2048, 1, 1}; 

但是,如果你改变你的内核到下面的内核,可以降低你的全局工作尺寸,以及:( )

__kernel void new_calc (__global int *A, __global int *B) 
{ 
    int i = get_global_id(0); 
    for (int ind = 0; ind < 8; ind++) 
    B[i*8 + ind] = A[i*8 + ind] * 5; 
} 

那么这种方式,您可以使用全局大小:

size_t global_work_size = {256, 1, 1}; 

而且与第二内核,每个线程将执行更多的工作,从而导致更多的利用。