2014-11-15 42 views
1

我開始學習OpenCl,並將其作爲我必須編寫的一個任務程序,即對數組中的所有元素進行求和。通過求和一個數組,OpenCL,交錯尋址無效結果

該程序應該是簡單的,我不知道我今天怎麼了,但它不工作。嗯,它確實,但有時它顯示錯誤的結果(有時不)。

我們擁有的元素越多,獲得錯誤結果的機會就越大(特別是在16536之後)。元素的數量總是等於2的冪數。

有人能告訴我,這裏有什麼問題嗎?

內核:

__kernel void Reduction_InterleavedAddressing(__global uint* array, uint stride) 
{ 
    unsigned int i = get_global_id (0); 
    unsigned int size = get_global_size(0); 

    if ((i % stride*2) == 0 && (i + stride)<size){ 
      array[i] += array[i+stride]; 
    } 
} 

內核調用:

unsigned int stride = 1; 
    clErr = clSetKernelArg(m_InterleavedAddressingKernel, 0, sizeof(cl_mem), (void*)&m_dPingArray); 

    for (; stride <= m_N/2 ; stride*=2){ 
     clErr = clSetKernelArg(m_InterleavedAddressingKernel, 1, sizeof(cl_int), (void*)&stride); 
     clErr = clEnqueueNDRangeKernel(CommandQueue, m_InterleavedAddressingKernel, 1, NULL, &globalWorkSize, LocalWorkSize, 0, NULL, NULL); 
     V_RETURN_CL(clErr, "Error executing kernel"); 
    } 

感謝你對你的祕訣提前

+1

什麼是LocalWorkSize?嘗試傳遞NULL而不是。在OpenCL 1.x中,如果您傳遞本地工作量,那麼全局工作量必須是其倍數。此外,這個內核可能對學習有好處,但它不是一個有效的簡化操作(隨着步伐的增加,工作項目實際上做的事情越來越少)。要調試您的算法,您可以在每次迭代後讀回緩衝區,以查看結果是否符合您的預期。 – Dithermaster

+0

如果工作項目在單個內核調用中讀取和寫入相同內存,那麼結果肯定是錯誤的。 在我看來,錯誤是在全局大小,每個迭代的大小應該減少,並請離開本地大小NULL,因爲該代碼是無關緊要的。 – DarkZeros

+0

嗨,謝謝你的答案。我再次寫了它,globalWorkSize =元素的數量,我把它每次除以兩,localSize = NULL,並在內核我重新排列每個步驟後的元素(把在開始) 它工作得更好,但仍有錯誤:( –

回答

0

我testet它。您必須將stride * 2設置爲(stride * 2)!對於我的解決方案,它運行良好

if ((i % (stride*2)) == 0 && (i + stride) < size) { 
    array[i] += array[i+stride]; 
} 
相關問題