forループ内でカーネルを繰り返し呼び出すCUDAプログラムがあります。 コードは、行列全体が完了するまで前の式で計算された値を使用して、行列のすべての行を計算します。 これは基本的に動的プログラミングアルゴリズムです。 以下のコードは、カーネルの と並行して、多くの別個の行列の(i、j)エントリを塗りつぶします。forループ内でカーネルを繰り返し呼び出すCUDAプログラムでパフォーマンスが低下する
for(i = 1; i <=xdim; i++){
for(j = 1; j <= ydim; j++){
start3time = clock();
assign5<<<BLOCKS, THREADS>>>(Z, i, j, x, y, z)
end3time = clock();
diff = static_cast<double>(end3time-start3time)/(CLOCKS_PER_SEC/1000);
printf("Time for i=%d j=%d is %f\n", i, j, diff);
}
}
カーネルassign5は私の問題は、私はこのプログラムを実行すると、各iとjのための時間が 時間の0ほとんどですが、時にはそれが10ミリ秒であるということである
__global__ void assign5(float* Z, int i, int j, int x, int y, int z) {
int id = threadIdx.x + blockIdx.x * blockDim.x;
char ch = database[j + id];
Z[i+id] = (Z[x+id] + Z[y+id] + Z[z+id])*dev_matrix[i][index[ch - 'A']];
}
}
簡単です。出力は次のようになります
Time for i=0 j=0 is 0
Time for i=0 j=1 is 0
.
.
Time for i=15 j=21 is 10
Time for i=15 j=22 is 0
.
私はこれがなぜ起こっているのか分かりません。スレッドの競合状態が表示されません。私は右のiとjについて、最初のループ時間後
if(i % 20 == 0) cudaThreadSynchronize();
を追加する場合、ほとんど0です。しかし、その後の同期のための時間 は時々10あるかさえ20 CUDAがで多くの操作 を実行しているように思えます低コストであり、その後の費用が高い。どんな助けもありがとう。
確かに時間ソースの精度が低すぎるため、これは単なるエイリアシングです。 – talonmies
変数Zとデータベースがデバイスのグローバル配列、dev_matrix、インデックスとデバイスの定数配列であることを追加するのを忘れました。メモリアクセスが統合されます。 – Ross
時計の解像度が約10msなので、結果は矛盾しています。ループ全体の時間を測定するほうが簡単です。高解像度、反復測定が必要な場合は、[この回答](http://stackoverflow.com/a/588377/324625)を参考にしてください。 –