2014-06-05 68 views
0

你好我想找到使用CUDA的數組元素的總和。CUDA發現數組元素的總和

__global__ void countZeros(int *d_A, int * B) 
{ 
    int index = blockIdx.x * blockDim.x + threadIdx.x; 
    B[0] = B[0]+d_A[index]; 
} 

所以最後,B [0]應該包含所有元素的總和。但我注意到B [0]每次都等於零。所以最後它只包含最後一個元素。 爲什麼B [0]每次都變爲零?

回答

3

所有線程正在寫入B[0],有些可能正在嘗試同時寫入。這行代碼:

B[0] = B[0]+d_A[index]; 

需要讀取和寫入B[0]。如果多個線程同時執行此操作,則會得到奇怪的結果。

您可以通過這樣做一個簡單的解決辦法:

atomicAdd(B, d_A[index]); 

,你應該得到有意義的結果(假設你有沒有錯誤的其他地方在你的代碼,你沒有顯示。)請務必進行初始化在調用這個內核之前,調用一些已知的值。

但是,如果您想有效地做到這一點,您應該研究cuda reduction sample或僅使用CUB

如果您在使用CUDA代碼時遇到問題,請務必使用proper cuda error checking

因此,如果仍然無法得到明智的結果,請用適當的cuda錯誤檢查來處理您的代碼,然後再問「我做了這個改變但仍不起作用,爲什麼?我不能告訴你爲什麼,因爲這是你顯示的唯一代碼片段。

+0

謝謝但atomicAdd是未定義的。我懷疑這是不可能的。看起來好像一個變種只能變一次。 – user3485986

+0

要使用'atomicAdd',您需要使用cc1.1或更高版本的GPU的架構開關編譯代碼。因此,例如,如果您有cc2.0 GPU,請在編譯命令行中添加「-arch = sm_20」。如果你確實有一個cc1.0 GPU,那麼這將不起作用,但是縮小示例代碼仍然可以工作。 –

+0

似乎太多擔心。也許這可以通過使用共享內存來完成? – user3485986