在 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
是最大值,而其他一些值不限于另一个的范围块中的线程。
您没有将求和正确同步到
blockDim.x
位置。在添加它们的总和之前,没有一个线程在等着看其他人写了什么。有点像
numer
.numer
写到内存位置高 threadId 获胜 b/c 它很有可能最后行动,我想。
为了快速求和,你想做的是对
s_shared[threadIdx.x]
numer
这需要 O(n) 的工作和 O(log n) 的时间。