'官方' CUDA减少功能不能接受某些数字?

时间:2016-03-03 20:07:35

标签: c++ cuda

目前正在尝试使用CUDA中的减少#3大纲pdf here

以下是我的缩减功能的外观

template <typename T>
__device__ void offsetReduction(planet<T> *bodies, T *outdata, int arrayIdent, int nbodies){
    extern __shared__ T sdata[];

    unsigned int tID = threadIdx.x;
    unsigned int i = tID + blockIdx.x * blockDim.x;

    if (arrayIdent == 1){
        if (i < nbodies){
            sdata[tID] = bodies[i].vx * bodies[i].mass;
        }

        __syncthreads();
    }

    if (arrayIdent == 2){
        if (i < nbodies){
            sdata[tID] = (bodies[i].vy * bodies[i].mass);
        }
        __syncthreads();
    }

    if (arrayIdent == 3){
        if (i < nbodies){
            sdata[tID] = (bodies[i].vz * bodies[i].mass);
        }
        __syncthreads();
    }

    for (unsigned int stride = blockDim.x / 2; stride > 0; stride >>=1)
    {
        if (tID < stride)
        {
            sdata[tID] += sdata[tID + stride];
        }
        __syncthreads();
    }

    if (tID == 0)
    {
        outdata[blockIdx.x] = sdata[0];
    }

然而,它似乎没有正常工作,所以我做了一些计算。

我启动了相同数量的线程和&#39; int nbodies&#39;,在我的情况下我选择了5.所以5个线程中的每一个都进来并为sdata []添加一个值没问题。然而,一旦它到达添加部分就会出错。

在第一次迭代中,线程0访问sdata [3],线程1访问sdata [4],其他线程不执行任何操作。在第二次迭代中,线程0访问sdata 1,其他线程不执行任何操作。然后,添加完成&#39;并且内核完成。但是sdata [2]永远不会被添加,所以我得到一个不正确的值存储在sdata [0]。

我错过了一些非常明显的东西吗? (我一直盯着这个,所以我可能有。

1 个答案:

答案 0 :(得分:1)

这个减少代码,就像任何其他&#34;树状&#34;减少操作,要求参与共享内存减少的线程数等于2的幂才能正常工作。

请注意,这意味着可以设计一个还原内核,该内核可以为每个块的2个线程的任何多个正确运行,具有最近的2个线程的较小功率执行实际减少。但是,您发布的代码不能像那样工作。