在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;

“结果”应始终在0到1之间,并且在整个块中应合计为1,但对于其中threadIdx.x为最大值的每个线程,它的值等于1.0,而其他线程的值不限于该范围在街区。

最佳答案

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

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

  • 我想,高threadId赢得b / c的可能性很大,那就是最后采取行动。

    为了快速求和,您要做的是对s_shared[threadIdx.x]
  • 每个人都写他们的数字
  • 一半的线程计算对的总和并将其写入新位置
  • 四分之一的线程计算成对的和,并将其写入新位置
  • ,直到只有一个线程和一个总和

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

    10-04 20:23