2017-08-22 39 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}; 

而且與第二內核,每個線程將執行更多的工作,從而導致更多的利用。