CUDA中的共享内存未获取分配给它的值,并且始终显示零

问题描述 投票:0回答:1

此简单的归约功能可在在线的CUDA演示文稿中找到。

__device__ void reducedSum(double* d_idata, double* d_odata, long LENGTH)
{
    extern __shared__ double sdata[];
    unsigned int tid = threadIdx.x;
    unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;

    if (i < LENGTH) {
        sdata[tid] = d_idata[i];
        __syncthreads();

        printf("Kernel sdata : %d \n", sdata[tid]);

        for (unsigned int s = 1; s < blockDim.x; s *= 2)
        {
            if (tid % (2 * s) == 0)
            {
                sdata[tid] += sdata[tid + s];
            }
            __syncthreads();

        }

        if (tid == 0) {
            d_odata[blockIdx.x] = sdata[0];
        }
    }
}

但是这里的printf总是打印以下输出。实际要做的是从d_idata数组中复制值,并将其部分分配给每个共享内存块。但是这不会发生。

enter image description here

对内核的调用如下:

long LENGTH = 10;
long N = 5;
int threadsPerBlock = N;
int numBlocks = (threadsPerBlock + LENGTH - 1) / threadsPerBlock;
cudaCalc<<<numBlocks, threadsPerBlock, N*sizeof(double)>>> (d_vec1, d_vec2, d_dotProduct, ....)

现在在内核内部,我将这个reduceSum __device__函数称为如下。

__global__ void cudaCalc(int* d_vec1, int* d_vec2, double* d_dotProduct, ... )
{
    int tid_0 = threadIdx.x;
    int index = blockDim.x * blockIdx.x + threadIdx.x;
    if (index < LENGTH) {
        d_dotProduct[index] = (double) d_vec1[index] * d_vec2[index];
        d_squared1[index] = (double)d_vec1[index] * d_vec1[index];
        d_squared2[index] = (double)d_vec2[index] * d_vec2[index];
        __syncthreads();
    }

    reducedSum(d_squared1, d_squaredSum1, LENGTH);
    reducedSum(d_squared2, d_squaredSum2, LENGTH);
    reducedSum(d_dotProduct, d_dotSum, LENGTH);

}

一些好先生/女士可以告诉我我哪里出问题了吗?我来这已经好几个小时了。如果您想查看其余的代码,请提出要求。预先谢谢你。

cuda shared-memory reduction
1个回答
0
投票

故障是由printf函数引起的。我不敢相信我花了几个小时。

printf("Kernel sdata : %d \n", sdata[tid]);

占位符是整数,而sdata是双精度数组。问题解决了。

非常糟糕,nvcc编译器不会针对此类错误显示警告或错误。另一方面,gcc显示很多警告。这应该是一个建议。

© www.soinside.com 2019 - 2024. All rights reserved.