私は休眠中のコードでホストスレッドでビジーウェイトを取り除く方法を探しています(そのコードをコピーしないでください、それは私の問題のアイデアを示すだけで、多くの基本的なバグがあります):
cudaStream_t steams[S_N];
for (int i = 0; i < S_N; i++) {
cudaStreamCreate(streams[i]);
}
int sid = 0;
for (int d = 0; d < DATA_SIZE; d+=DATA_STEP) {
while (true) {
if (cudaStreamQuery(streams[sid])) == cudaSuccess) { //BUSY WAITING !!!!
cudaMemcpyAssync(d_data, h_data + d, DATA_STEP, cudaMemcpyHostToDevice, streams[sid]);
kernel<<<gridDim, blockDim, smSize streams[sid]>>>(d_data, DATA_STEP);
break;
}
sid = ++sid % S_N;
}
}
ホストスレッドをアイドル状態にして、何らかのストリームが終了するのを待ってから、別のストリームを準備して実行する方法はありますか?
編集:ビジーウェイトを強調するために、コードにwhile(true)を追加しました。ここで、すべてのストリームを実行し、そのうちのどれが別の新しいストリームの実行を終了したかを確認します。cudaStreamSynchronize
特定のストリームが終了するのを待ちますが、最初にジョブを終了したストリームのいずれかを待ちたいです。
EDIT2:私は忙しいのをやめました-休眠の方法で待っています:
cudaStream_t steams[S_N];
for (int i = 0; i < S_N; i++) {
cudaStreamCreate(streams[i]);
}
int sid = 0;
for (int d = 0; d < DATA_SIZE; d+=DATA_STEP) {
cudaMemcpyAssync(d_data, h_data + d, DATA_STEP, cudaMemcpyHostToDevice, streams[sid]);
kernel<<<gridDim, blockDim, smSize streams[sid]>>>(d_data, DATA_STEP);
sid = ++sid % S_N;
}
for (int i = 0; i < S_N; i++) {
cudaStreamSynchronize(streams[i]);
cudaStreamDestroy(streams[i]);
}
ただし、ホストスレッドでビジーウェイトを使用しているバージョンよりも少し遅いようです。これは、現在、ストリームにジョブを静的に分散しているためだと思います。そのため、1つのストリームが作業を終了すると、各ストリームが作業を終了するまでアイドル状態になります。以前のバージョンでは、作業が最初のアイドルストリームに動的に分散されたため、より効率的でしたが、ホストスレッドでビジーウェイトが発生していました。