CUDA的金额减少有什么问题?

CUDA的金额减少有什么问题?,cuda,Cuda,我试图对包含452591个元素的数组执行求和归约,所有元素都设置为1,所以求和应该是452591 我将线程数nThreads计算为2的下一次幂,因此它是524288。在while循环的每次迭代中,只有前半个线程应该工作,在第i个元素处添加另一半的值。只有在nvalues上设置的元素数组数中存在实际值时,才会进行加法 它适用于12710251072甚至8271个元素。但不是用452591,我知道原因。452591个元素的输出为88064 __global__ void sum_kernel(int

我试图对包含452591个元素的数组执行求和归约,所有元素都设置为1,所以求和应该是452591

我将线程数
nThreads
计算为2的下一次幂,因此它是524288。在while循环的每次迭代中,只有前半个线程应该工作,在第i个元素处添加另一半的值。只有在
nvalues
上设置的元素数组数中存在实际值时,才会进行加法

它适用于12710251072甚至8271个元素。但不是用452591,我知道原因。452591个元素的输出为88064

__global__ void sum_kernel(int nvalues, double nThreads, double *values)
{   int i = blockIdx.x * blockDim.x + threadIdx.x;
    while (nThreads > 1)
    {   int middle = nThreads / 2;
        int j = i + middle;
        if ( i < middle )
        {   if (j < nvalues )
            {   values[i] += values[j]; }
            else
            {   values[i] += 0;  }
        }
        __syncthreads();
        nThreads = middle;
    }
    if (i == 0)
        printf("T0 ------> %0.f \n", values[0] );
}
内核用1个dim块调用,MAX_TPB=1024

sum\u kernel>(nvalue、next2Pow、values\u设备)

此外,我还检查了设备数组中的值是否正确,因为我可以将它们复制到主机数组中,并在主机中正确获取总和

但是由于学习的原因,我希望内核能够工作

CUDA的金额减少有什么问题

在CUDA中,与内核启动(网格)相关联的线程不会在锁步中一起执行。库达

您试图将整个数据集一分为二的方法依赖于网格中所有线程的协同工作。您可能还认为
\uu syncthreads()
会同步网格中的所有线程(这将使之成为可能),但事实并非如此。它只是


如果您想学习如何在CUDA中编写快速并行缩减,那么最好的出发点是有一个CUDA,它提供了演示中涵盖的各种方法的全面实施。

我认为您不了解CUDA执行的本质,因此,全局内存的减少无法工作,因为只有
\uu syncthreads()
。如果您想学习如何编写一个好的并行缩减,请尝试并附带一个cuda缩减示例代码。与其说上面的“无法工作”,我可能应该说“不能保证在数据集大小大于2048的情况下正常工作”@RobertCrovella我正在尝试幻灯片35中的示例,但是我得到了这个错误:没有函数模板“warpReduce”的实例与参数列表匹配参数类型是:(int[],unsigned int)您可能还想查看这个站点上的CUDA文档。虽然没有太多,但并行简化是存在的:如果您在实现幻灯片中的代码时遇到问题,您可能希望参考已经实现的。若要解决该特定问题,请将其更改为:
if(tid<32)warpReduce(sdata,tid)对此:
如果(tid<32)数据减少(sdata,tid)
int expo = ceil(log(n) / log(base));
double next2Pow = (double) pow(base, expo)