我从斯坦福找到了使用共享内存的this并行缩减代码。
代码是1<<< 18数量的元素的示例,其等于262144并且获得正确的结果。
为什么对于一定数量的元素,我得到了正确的结果,对于其他数量的元素,如200000或25000,我会得到与预期不同的结果? 在我看来它总是指定所需的线程块
答案 0 :(得分:1)
// launch a single block to compute the sum of the partial sums
block_sum<<<1,num_blocks,num_blocks * sizeof(float)>>>
此代码导致错误。
假设numblocks是13,
然后在内核blockDim.x / 2将是6, 和
if(threadIdx.x < offset)
{
// add a partial sum upstream to our own
sdata[threadIdx.x] += sdata[threadIdx.x + offset];
}
只会添加导致错误的前12个元素。
当元素数为200000或250000时,num_blocks将为奇数并导致错误,即使是num_blocks它也能正常工作
答案 1 :(得分:0)
此内核对内核的阻塞参数(网格和线程块大小)很敏感。您是否使用足够的线程调用它来覆盖输入大小?
使用for循环来构造这样的内核更加健壮 - 而不是:
unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
类似的东西:
for ( size_t i = blockIdx.x*blockDim.x + threadIdx.x;
i < N;
i += blockDim.x*gridDim.x ) {
sum += in[i];
}
CUDA手册中的源代码有很多“阻止不可知”代码的例子。缩减代码在这里:
https://github.com/ArchaeaSoftware/cudahandbook/tree/master/reduction