2017-04-10 40 views
0

我想通過與3D音量位置和組ID識別來計算每個組的本地總和。OpenCL NDrangekernel與3d全局大小和3d本地大小

我的想法是將空間分成組並使用atomic_add來計算local_sum。但是因爲我對並行計算並不熟悉,所以很難找到代碼和指令之間的相關性。 我現在的內核是這樣的:

__kernel void TestAtomicAddLocal(__global *int src, int3 size, __global int *res) 
{ 
    int x = get_global_id(0); 
    int y = get_global_id(1); 
    int z = get_global_id(2); 
    if(x >= vol_dim.x || y >= vol_dim.y || z >= vol_dim.z){ return; } 
    int id = x + y * vol_dim.x + z * vol_dim.x * vol_dim.y; 

    // local mem shared by all work items in work group, 
    //so this can be accessed by all items in current workgroup 
    __local int local_sum; 
    local_sum= 0; 

    // use global_id to access the value of input array 
    int local_offset = atomic_add(&local_sum, src[id]); 
    barrier(CLK_LOCAL_MEM_FENCE); 

    int global_offset = atomic_add(&num_verts[0], local_sum); 
    barrier(CLK_GLOBAL_MEM_FENCE); 
} 

對於主機部分,我的設置是

enqueueNDrangeKernel(cq, kn_testAtomicAddLocal, 3, 0, cl::size3(256,256,256), cl::size3(64, 64, 64), 0, 0, 0); 

對於kenrnel參數,* src爲cl_mem大小爲256*256*256*sizeof(cl_int),大小爲4 * sizeof(cl_int)和* RES是cl_mem,尺寸爲4*sizeof(int)。 然後我得到的錯誤,CL_OUT_OF_RESOURCE和CL_INVALID_GROUP_SIZE,從我的理解,我的設備最大組大小爲1024,但這裏總組=(256/64)^ 3 = 64 < 1024. 我的GPU最大工作項目大小是1024x1024也沒關係。所以我認爲我必須明白一件事是錯的。我希望有人能幫助我。

回答

0

最大組大小限制了您的64 * 64 * 64部分。

我猜你正在使用CUDA卡。你最好在CUDA卡上使用CUDA。 OpenCL在CUDA卡上或多或少地被仿效。如果你不是的話,我認爲所有的AMD顯卡都有256個組的大小限制。編輯:嗯......我忘了英特爾的。如果是這樣,請忽略此部分。

還有一件重要的事情,你最好先查看一下互聯網上的一些簡化邏輯實現示例。 Atomics非常有前途,像你所做的那樣使用它們幾乎可以確定你的GPU代碼比CPU更慢。

+0

我使用的是CUDA卡,但我的程序需要在各種顯卡上運行,所以我必須使用OpenCL。你的意思是像一個本地的減少和全球減少,而不是在不同的領域的兩個atomic_add權利?我只是不想在我的內核文件中編寫太多的內核函數。你能推薦我的OpenCL資源嗎? – EdwinDebuger

+0

@EdwinDebuger我記得在AMD的SDK中有樣本,但我不確定。我認爲對於你的情況,你可以使用更小的塊,讓一個線程處理更多的元素。 – BlueWanderer

+0

@EdwinDebuger更通用的解決方案是在GPU上進行局部縮減,而不是在全局上減少CPU。但是,在進行每組縮減之前,仍然需要執行每線程本地本地減少。並且組的最佳數量取決於GPU的容量而不是作業的大小。 – BlueWanderer