如何解决右侧的 CUDA 总和
我正在尝试使用 CUDA 实现总和减少,但是我希望减少是向右而不是向左.. 我写了下面的代码,但我不知道为什么它不起作用
__global__ void reduce_kernel(
float *input,float *partialSums,unsigned int N)
{
unsigned int segment = blockIdx.x * blockDim.x * 2;
unsigned int i = segment + threadIdx.x;
__shared__ float input_s[BLOCK_DIM];
input_s[threadIdx.x] = input[i] + input[i + BLOCK_DIM];
int count = 2;
__syncthreads();
for (unsigned int stride = BLOCK_DIM / 2;
stride < BLOCK_DIM;
stride = stride + (BLOCK_DIM / count))
{
if (threadIdx.x >= stride) {
count = count * 2;
input_s[threadIdx.x] += input_s[threadIdx.x - stride];
printf("%d ",stride);
__syncthreads();
if (stride == BLOCK_DIM - 1) {
break;
}
}
__syncthreads();
}
if (threadIdx.x == BLOCK_DIM - 1) {
partialSums[blockIdx.x] = input_s[threadIdx.x];
}
}
知道我做错了什么吗?
解决方法
只要输入的元素数是 2 的幂,这应该完全符合您的要求。部分总和应以右侧结束。这种算法的步幅必须从 1
增长到 BLOCK_DIM / 2
(产生更多的扭曲发散)或从 BLOCK_DIM / 2
缩小到 1
。无论哪种方式,它都应该乘以/除以 2
。
__global__ void reduce_kernel(
float *input,float *partialSums,unsigned int N)
{
unsigned int segment = blockIdx.x * blockDim.x * 2;
unsigned int i = segment + threadIdx.x;
__shared__ float input_s[BLOCK_DIM];
input_s[threadIdx.x] = input[i] + input[i + BLOCK_DIM];
__syncthreads();
for (unsigned int stride = BLOCK_DIM / 2;
stride > 0;
stride /= 2)
{
if (threadIdx.x >= BLOCK_DIM - stride) {
input_s[threadIdx.x] += input_s[threadIdx.x - stride];
}
__syncthreads();
}
if (threadIdx.x == BLOCK_DIM - 1) {
partialSums[blockIdx.x] = input_s[threadIdx.x];
}
}
条件中的 __syncthreads();
是另一个错误,因为块的所有线程都必须参与同步。否则会导致未定义的行为。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。