2009-07-01 47 views
3

在CUDA內核,我具有類似於下面的代碼。我試圖計算每個線程一個分子,並在分塊上累積分子以計算分母,然後返回比率。然而,CUDA被設置爲任何值的塊計算NUMER由線程擁有最大threadIdx.x,而不是在塊穿過的所有線程計算的NUMER值的總和DENOM的價值。有誰知道發生了什麼事?CUDA共享存儲器陣列 - 古怪行爲

extern __shared__ float s_shared[]; 

float numer = //calculate numerator 

s_shared[threadIdx.x] = numer; 
s_shared[blockDim.x] += numer; 
__syncthreads(); 

float denom = s_shared[blockDim.x]; 
float result = numer/denom; 

「結果」應始終爲0和1之間,並應在整個塊總和爲1,而是它等於1.0每個線程,其中threadIdx.x爲最大,以及一些其他值並不侷限於到塊中其他線程的範圍。

回答

4

你沒有正確同步求和到blockDim.x位置。在添加總和之前,沒有任何線程正在等待查看別人寫的內容。有點像

  • 大家讀數爲零,
  • 回家,計算零+ NUMER。
  • EVERONE寫入零+ NUMER到所述存儲器位置

高的threadId勝B/C它具有最後作用的可能性高,我想。

你想做的事,而不是爲了做一個快速的總和什麼,是做對 s_shared[threadIdx.x]

  • 大家二進制和寫入他們的NUMER
  • 一半的線程計算對資金和寫那些到新的位置
  • 線程的四分之一caluclate對對的總和,並寫那些到新的位置
  • 直到ÿ OU只是有一個線程和一個總和

這需要O(n)的工作和O(log n)的時間。

+4

爲了說明這一點,這裏的邏輯被稱爲簡化。在cuda sdk中有幾個這樣的例子。請參閱:cuda-sdk/C/src/reduction/reduction_kernel.cu – 2010-03-05 19:08:23