CUDA共享内存数组 - 奇怪的行为

时间:2009-07-01 21:01:02

标签: c cuda gpu gpgpu

在CUDA内核中,我的代码类似于以下内容。我试图计算每个线程的一个分子,并在块上积累分子来计算分母,然后返回比率。但是,CUDA将denom的值设置为具有最大threadIdx.x的块中的线程为数值计算的值,而不是块中所有线程计算的数值的总和。有谁知道发生了什么?

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;

“result”应始终在0和1之间,并且应该在整个块中总和为1,但对于threadIdx.x为最大值的每个线程,它等于1.0,而其他一些值不限于块中的其他线程。

1 个答案:

答案 0 :(得分:4)

您没有正确地将求和同步到blockDim.x位置。在添加总和之前,所有线程都没有等待查看其他人写的内容。有点像

  • 每个人都读零,
  • 回家,计算零+数字。
  • Everone将零+数字写入内存位置

我认为高线程ID赢得b / c很有可能最后一次表现。

为了做一个快速的总和,你想要做的是做二进制求和 s_shared[threadIdx.x]

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

这需要O(n)工作和O(log n)时间。