当试图找出多个内核是否可以访问共享内存时,我发现有时共享内存中的数据在被另一个内核访问时仍然存在,但有时却没有。更重要的是,当通过cuda-gdb调试程序时,前一个内核在共享内存中写入的数据总是可以被下一个内核读取。
以下是一段测试代码,包含2gpus。
extern __shared__ double f_ds[];
__global__ void kernel_writeToSharedMem(double* f_dev, int spd_x)
{
int tid_dev_x = (blockDim.x * blockIdx.x + threadIdx.x);
int tid_dev_y = (blockDim.y * blockIdx.y + threadIdx.y);
int tid_dev = tid_dev_y* spd_x + tid_dev_x;
if(tid_dev < blockDim.x * blockDim.y * gridDim.x*gridDim.y)
f_ds[threadIdx.y*blockDim.x+threadIdx.x] = 0.12345;
__syncthreads()
}
__global__ void kernel_readFromSharedMem(double *f_dev, int dev_no, int spd_x)
{
int tid_dev_x = (blockDim.x * blockIdx.x + threadIdx.x);
int tid_dev_y = (blockDim.y * blockIdx.y + threadIdx.y);
int tid_dev = tid_dev_y* spd_x + tid_dev_x;
if(tid_dev < blockDim.x * blockDim.y * gridDim.x*gridDim.y)
{
f_dev[tid_dev] = f_ds[threadIdx.y*blockDim.x+threadIdx.x];
printf("threadID %d in dev [%d] is having number %f\n",
tid_dev,dev_no,f_ds[threadIdx.y*blockDim.x+threadIdx.x]);
}
__syncthreads();
}
int main()
{
...
dim3 block_size(BLOCK_SIZE,BLOCK_SIZE);
im3 grid_size(spd_x/BLOCK_SIZE,spd_y/BLOCK_SIZE);
for(int i = 0; i < ngpus; i++)
{
cudaSetDevice(i);
kernel_writeToSharedMem<<<grid_size,block_size,sizeof(double)*BLOCK_SIZE*BLOCK_SIZE,stream[i]>>>(f_dev[i],spd_x);
cudaDeviceSynchronize();
cudaThreadSynchronize();
}
for(int i = 0; i < ngpus; i++)
{
cudaSetDevice(i);
kernel_reaFromSharedMem<<<grid_size,block_size,sizeof(double)*BLOCK_SIZE*BLOCK_SIZE,stream[i]>>>(f_dev[i], int i, spd_x);
cudaDeviceSynchronize();
cudaThreadSynchronize();
}
...
}
运行程序后出现4种情况。
1)Dev0为0.12345但Dev1为0;
2)Dev0为0但Dev1为0.12345;
3)Dev0和Dev1均为0;
4)Dev0和Dev1均为0.12345。
在cuda-gdb中运行4)总是如此。
这是否表明共享内存的持久性只是一个内核?只有一个内核偶尔会清除或释放共享内存吗?
答案 0 :(得分:4)
保证共享内存仅具有分配给它的块的生命周期。任何尝试从块到块或内核启动到内核启动重用共享内存都是完全未定义的行为,并且永远不会依赖于理智的代码设计。