我对CUDA样本“CUDA可分离卷积”中的代码有疑问。为了进行行卷积,此代码首先将数据加载到共享内存中。使用指针算术,每个线程将输入指针移动到它们自己的位置,然后将一些全局内存写入共享内存。以下是令我困惑的代码:
__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];
}
...
据我了解此代码,每个线程将计算自己的baseX
和baseY
值,然后所有活动线程将开始增加指针{ {1}}和d_Src
同时。
所以,根据我的知识,如果数组d_Dst
和d_Src
在本地内存中(例如每个线程都有自己的数组副本),这将是正确的。但是这个阵列在全局设备内存中!那么会发生什么,所有活动线程都会增加指针,结果将是不正确的。可以解释一下,为什么这有效?
由于
答案 0 :(得分:2)
它的工作原理是因为每个线程都有自己的指针副本。
void foo(float* bar){
bar++;
}
float* test = 0;
foo(test);
cout<<test<<endl; //will print 0