2009-07-01 31 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