__global__ 内核中棘手的数组算法(CUDA 样本)

Tricky array arithmetics inside a __global__ kernel (CUDA samples)

我对 CUDA 示例 "CUDA Separable Convolution" 中的代码有疑问。为了进行行卷积,此代码首先将数据加载到共享内存中。使用指针算法,每个线程将输入指针移动到它们自己的位置,然后将一些全局内存写入共享内存。这是让我感到困惑的一段代码:

__global__ void convolutionRowsKernel(
    float *d_Dst,
    float *d_Src,
    int imageW,
    int imageH,
    int pitch
    )
{
    __shared__ float s_Data[ROWS_BLOCKDIM_Y][(ROWS_RESULT_STEPS + 2 *     ROWS_HALO_STEPS) * ROWS_BLOCKDIM_X];

    //Offset to the left halo edge
    const int baseX = (blockIdx.x * ROWS_RESULT_STEPS - ROWS_HALO_STEPS) * ROWS_BLOCKDIM_X + threadIdx.x;
    const int baseY = blockIdx.y * ROWS_BLOCKDIM_Y + threadIdx.y;

    d_Src += baseY * pitch + baseX;
    d_Dst += baseY * pitch + baseX;

    //Load main data
#pragma unroll

    for (int i = ROWS_HALO_STEPS; i < ROWS_HALO_STEPS + ROWS_RESULT_STEPS; i++)
    {
        s_Data[threadIdx.y][threadIdx.x + i * ROWS_BLOCKDIM_X] = d_Src[i * ROWS_BLOCKDIM_X];
    }
...

据我理解这段代码,每个线程都会计算自己的baseXbaseY值,之后所有个活动线程会开始增加指针d_Srcd_Dst同时

因此,据我所知,如果数组 d_Srcd_Dst 位于本地内存中(例如,每个线程都会有自己的数组副本),这将是正确的。但是这个数组在全局设备内存中!那么会发生什么,所有活动线程都会增加指针,结果不正确。谁能解释一下,为什么这行得通?

谢谢

之所以有效,是因为每个线程都有自己的指针副本。

void foo(float* bar){
    bar++;
}

float* test = 0;
foo(test);
cout<<test<<endl; //will print 0