如何将cuda输入数组复制到共享数组?

时间:2019-04-21 20:43:04

标签: cuda shared-memory

我正在尝试将cuda输入数组复制到共享内存数组中。前n个值完美地复制到共享数组中,但是此后发生了一些非常奇怪的模式。谁能找到我在做什么错/这里发生了什么?

我尝试使用s_x [tid] = x [tid],s_x [row] = x [row]以及其他两个组合。我知道他们在逻辑上是没有道理的,但必须尝试一切。

这是我写的内核函数:

    __global__ void mv_cuda_shared(float* y, float* A, float* x, int n)
    {
        extern __shared__ float s_x[];
        int row = blockIdx.x * blockDim.x + threadIdx.x;
        int tid = threadIdx.x;
        s_x[row] = x[row];
        __syncthreads();
        if(tid == 0 && row == 0)
                for(int i = 0; i < n; i++){printf("s_x[%d] = %10.6f x = %10.6f\n", i, s_x[i], x[i]);}
        float temp = 0;
        if(row < n)
        {
            for(int k = 0; k < n; k++)
            {
                temp += (A[row*n + k] * s_x[k]);
            }
        }
        y[row] = temp;
    }

这是我在main方法中调用它的地方(省略所有cuda malloc和复制):

    mv_cuda_shared<<<(N/BLOCK_SIZE), BLOCK_SIZE, N*sizeof(float)>>>(d_y, d_A, d_x, N);

所以我希望s_x匹配x。但是,相反,前N个(n = N)元素被正确复制,但是其余元素似乎遵循一个模式。例如,s_x [N-1]之后的4个条目说为1。然后,之后的4个条目为.24566 ....(我检查一下,并且该数字甚至不在原始数组中)。那么,谁能看到我做错了什么?

1 个答案:

答案 0 :(得分:1)

此代码中的所有内容都没有多大意义,但是,如果要真正地为每个块将全局存储阵列的n个元素加载到共享内存中,则复制代码必须类似于:

    extern __shared__ float s_x[];
    int tid = threadIdx.x;
    for(int i=tid; i<n; i+=blockDim.x) {
       s_x[i] = x[i];
    }
    __syncthreads();

但是,我怀疑这确实是您所需要的,并且怀疑您可能怀有s_x在所有块之间共享的(不正确的)概念,而不是在块范围内共享,这意味着每个块都有其自己的位置。在共享内存中拥有该阵列的完整副本。