在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;
result
应该总是在0和1之间,并且应该在整个块中总和为1,但是对于每个线程,它等于1.0,其中threadIdx.x
是最大值,并且其他值不限于块中其他线程的范围。
1条答案
按热度按时间ecfsfe2w1#
您没有将求和正确同步到
blockDim.x
位置。没有一个线程在添加它们的总和之前等待查看其他线程写了什么。有点像1.每个人都读零
1.回到家,计算零+
numer
。1.每个人都将0 +
numer
写入内存位置高threadId赢得B/c它有一个最后行动的可能性很高,我想。
为了快速求和,您需要对
s_shared[threadIdx.x]
进行二进制求和1.每个人都写他们的
numer
1.一半的线程计算对的和并将它们写入新的位置
1.四分之一的线程计算对的和,并将它们写入新的位置
1.等等
1.直到你只有一条线和一个和
这需要O(n)的工作和O(log n)的时间。