3

在 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,并且某些其他值不限于其他线程的范围在块中。

4

1 回答 1

4

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

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

我想,高 threadId 赢得 b/c 它很有可能最后行动。

为了快速求和,您想要做的是在 s_shared[threadIdx.x]

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

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

于 2009-07-01T21:23:13.083 回答