最近CUDAについて勉強しています。CUDAのメモリアクセス時間について知りたいです。
では、CUDA プログラミング ガイドに書かれているメモリ アクセス時間:
- グローバル メモリ アクセス時間は 400 ~ 600 サイクル
- 共有メモリ ( L1 キャッシュ ) アクセス時間は 20 ~ 40 サイクル
サイクルは時計と同じだと思います。これは正しいです ?ということで、メモリアクセス時間を調べてみました。ホストは固定されていますが、カーネル コードには 3 つのバージョンがあります。これは私のコードです:
ホストコード
float* H1 = (float*)malloc(sizeof(float)*100000);
float* D1;
for( int i = 0 ; i < 100000 ; i++ ){
H1[i] = i;
}
cudaMalloc( (void**)&D1, sizeof(float)*100000);
cudaMemcpy( D1, H1, sizeof(float)*100000, cudaMemcpyHostToDevice );
cudaPrintfInit();
test<<<1,1>>>( D1 );
cudaPrintfDisplay(stdout, true);
cudaPrintfEnd();
カーネル バージョン 1
float Global1;
float Global2;
float Global3;
int Clock;
Clock = clock();
Global1 = Dev_In1[1];
Clock = clock() - Clock;
cuPrintf("Global Memory Access #1 : %d\n", Clock );
Clock = clock();
Global2 = Dev_In1[2];
Clock = clock() - Clock;
cuPrintf("Global Memory Access #2 : %d\n", Clock );
Clock = clock();
Global3 = Dev_In1[3];
Clock = clock() - Clock;
cuPrintf("Global Memory Access #3 : %d\n", Clock );
結果です
グローバルメモリアクセス #1 : 882
グローバルメモリアクセス #2 : 312
グローバルメモリアクセス #3 : 312
Dev_In[2]、Dev_In[3]がキャッシュされているので、1回目のアクセスはキャッシュではないので800サイクルかかりましたが、2回目のアクセス3回目のアクセスは312サイクルかかったと思います。
カーネル バージョン 2
int Global1, Global2, Global3;
int Clock;
Clock = clock();
Global1 = Dev_In1[1];
Clock = clock() - Clock;
cuPrintf("Global Memory Access #1 : %d\n", Clock );
Clock = clock();
Global2 = Dev_In1[50000];
Clock = clock() - Clock;
cuPrintf("Global Memory Access #2 : %d\n", Clock );
Clock = clock();
Global3 = Dev_In1[99999];
Clock = clock() - Clock;
cuPrintf("Global Memory Access #3 : %d\n", Clock );
その結果です
グローバルメモリアクセス #1 : 872
グローバルメモリアクセス #2 : 776
グローバルメモリアクセス #3 : 782
初回アクセス時に Dev_In1[50000] と Dev_In2[99999] がキャッシュされていないと思います
だから… #1,#2,#3 遅れてる…
カーネル バージョン 3
int Global1, Global2, Global3;
int Clock;
Clock = clock();
Global1 = Dev_In1[1];
Clock = clock() - Clock;
cuPrintf("Global Memory Access #1 : %d\n", Clock );
Clock = clock();
Global1 = Dev_In1[50000];
Clock = clock() - Clock;
cuPrintf("Global Memory Access #2 : %d\n", Clock );
Clock = clock();
Global1 = Dev_In1[99999];
Clock = clock() - Clock;
cuPrintf("Global Memory Access #3 : %d\n", Clock );
結果
グローバルメモリアクセス #1 : 168
グローバルメモリアクセス #2 : 168
グローバルメモリアクセス #3 : 168
この結果はわかりません
Dev_In[50000]、Dev_In[99999]はキャッシュされていませんが、アクセス時間は非常に高速です!! ただ、私は1つの変数を使用しました....
SO .. 私の質問は、gpu サイクル == gpu クロックですか?
また、result1、result2、result3 では、result3 のメモリ アクセス時間が非常に速いのはなぜですか?