CUDA共享内存阵列-奇数行为

CUDA共享内存阵列-奇数行为,c,cuda,gpu,gpgpu,C,Cuda,Gpu,Gpgpu,在CUDA内核中,我有如下类似的代码。我试图计算每个线程一个分子,然后在块上累加这些分子来计算分母,然后返回比率。但是,CUDA正在将denom的值设置为具有最大threadIdx.x的块中的线程为numer计算的任何值,而不是块中所有线程计算的numer值之和。有人知道发生了什么事吗 extern __shared__ float s_shared[]; float numer = //calculate numerator s_shared[threadIdx.x] = numer; s

在CUDA内核中,我有如下类似的代码。我试图计算每个线程一个分子,然后在块上累加这些分子来计算分母,然后返回比率。但是,CUDA正在将denom的值设置为具有最大threadIdx.x的块中的线程为numer计算的任何值,而不是块中所有线程计算的numer值之和。有人知道发生了什么事吗

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,但对于threadIdx.x为最大值的每个线程,结果应等于1.0,并且某些其他值不限于块中其他线程的范围

您没有将求和正确同步到
blockDim.x
位置。没有线程在添加它们的总和之前等待查看其他线程写了什么。有点像

  • 每个人都读零
  • 回家,计算零+数字
  • Everone将零+数字写入内存位置
高线程ID赢得b/c,我想它很有可能最后一次执行

相反,为了进行快速求和,您要做的是对
s\u共享[threadIdx.x]

  • 每个人都写自己的数字
  • 一半的线程计算对的和,并将它们写入一个新位置
  • 四分之一的线程计算成对的总和,并将其写入新位置
  • 直到你只有一个线程和一个总和

这需要O(n)功和O(logn)时间。

为了记下这一点,这里的逻辑称为约化。cuda sdk中有一些这样的示例。请参阅:cudasdk/C/src/reduce/reduce\u kernel.cu