CUDA 共享内存阵列 - 奇怪的行为

问题描述 投票:0回答:1

在 CUDA 内核中,我有类似于以下的代码。我试图为每个线程计算一个分子,并在块上累加分子以计算分母,然后返回比率。但是,CUDA 将

denom
的值设置为块中具有最大
numer
的线程为
threadIdx.x
计算的任何值,而不是跨块中所有线程计算的
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;

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

c cuda reduce gpgpu gpu-shared-memory
1个回答
4
投票

您没有将求和正确同步到

blockDim.x
位置。在添加它们的总和之前,没有一个线程在等着看其他人写了什么。有点像

  1. 大家读零,
  2. 回家,计算零+
    numer
    .
  3. 大家把零+
    numer
    写到内存位置

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

为了快速求和,你想做的是对

s_shared[threadIdx.x]

  1. 每个人都写下他们的
    numer
  2. 一半的线程计算对的总和并将它们写入新位置
  3. 四分之一的线程计算对的总和,并将它们写入新位置
  4. 直到你只有一个线程和一个总和

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

© www.soinside.com 2019 - 2024. All rights reserved.