对我来说,cuda 设备上的共享内存如何工作是个谜。我很想计算可以访问相同共享内存的线程。为此我写了一个简单的程序
#include <cuda_runtime.h>
#include <stdio.h>
#define nblc 13
#define nthr 1024
//------------------------@device--------------------
__device__ int inwarpD[nblc];
__global__ void kernel(){
__shared__ int mywarp;
mywarp=0;
for (int i=0;i<5;i++) mywarp += (10000*threadIdx.x+1);
__syncthreads();
inwarpD[blockIdx.x]=mywarp;
}
//------------------------@host-----------------------
int main(int argc, char **argv){
int inwarpH[nblc];
cudaSetDevice(2);
kernel<<<nblc, nthr>>>();
cudaMemcpyFromSymbol(inwarpH, inwarpD, nblc*sizeof(int), 0, cudaMemcpyDeviceToHost);
for (int i=0;i<nblc;i++) printf("%i : %i\n",i, inwarpH[i]);
}
并在 K80 GPU 上运行它。由于多个线程可以访问同一个共享内存变量,我期待这个变量将被更新 5*nhr 次,尽管由于银行冲突而不是在同一个周期。但是,输出表明mywarp共享变量仅更新了 5 次。对于每个块,不同的线程完成了这个任务:
0 : 35150005
1 : 38350005
2 : 44750005
3 : 38350005
4 : 51150005
5 : 38350005
6 : 38350005
7 : 38350005
8 : 51150005
9 : 44750005
10 : 51150005
11 : 38350005
12 : 38350005
相反,我期待
523776*10000+5*1024=5237765120
对于每个块。有人可以解释一下我对共享内存的理解在哪里失败。我还想知道一个块中的所有线程如何访问(更新)相同的共享变量。我知道在同一个 MP 周期是不可能的。序列化对我来说很好,因为这将是一个罕见的事件。