有人可以帮我理解以下CUDA-C的部分并行求和算法实现吗?我很难理解共享partialSum
数组的初始填充 [第 3 到 8 行]。我已经追踪了几个小时,但我不明白为什么应该从下面的代码开始而2*blockIdx.x*blockDim.x;
不是blockIdx.x*blockDim.x;
?
主机代码:
numOutputElements = numInputElements / (BLOCK_SIZE<<1);
if (numInputElements % (BLOCK_SIZE<<1)) {
numOutputElements++;
}
#define BLOCK_SIZE 512
dim3 dimGrid(numOutputElements, 1, 1);
dim3 dimBlock(BLOCK_SIZE, 1, 1);
total<<<dimGrid, dimBlock>>>(deviceInput, deviceOutput, numInputElements);
内核代码:
1 __global__ void total(float * input, float * output, int len) {
2
3 __shared__ float partialSum[2*BLOCK_SIZE];
4
5 unsigned int t = threadIdx.x;
6 unsigned int start = 2*blockIdx.x*blockDim.x;
7 partialSum[t] = input[start + t];
8 partialSum[blockDim.x + t] = input[start + blockDim.x + t];
9
10 for (unsigned int stride = blockDim.x; stride >=1; stride >>=1)
11 {
12 __syncthreads();
13
14 if (t < stride)
15 partialSum[t] += partialSum[t + stride];
16 }
17 output[blockIdx.x] = partialSum[0];
18 }
假设我有 10 个元素要求和,我选择将块大小设为 4,每个块有 4 个线程,所以将有 3 个块在使用,对吧?[让我们暂时忘记经线大小和其他事情]
当 blockIdx.x 为 2 (具有 2 个元素的最后一个块)时,开始变为 (2*2*4=)16 并且大于 10 并且超过input
长度(因此partialSum[t]
和partialSum[blockDim.x + t]
都将保持不变并且block2
's共享内存将保持为空。)如果是这样,那么我数组的最后 2 个元素将丢失!
这让我觉得我得到了 blockIdx.x, blockDim.x 错误的方式。有人可以纠正我吗?请!