1

CUDA ストリームを使用して、非同期データ転送を有効にし、メモリ コピーのレイテンシを隠しています。2 つの CPU スレッドと 2 つの CUDA ストリームがあります。1 つは、最初の CPU スレッドによって開始された一連の cudaMemcpyAsync 呼び出しである「データ」ストリームであり、もう 1 つは、計算カーネルを実行する「計算」ストリームです。データ ストリームはコンピューティング ストリームのバッチを準備しているため、ストリームが処理するバッチが完全にメモリに読み込まれるようにすることがコンピューティング ストリームにとって重要です。

そのような同期またはその他のメカニズムに CUDA イベントを使用する必要がありますか?

更新:各ストリームでデータのコピー/計算を使用して個別のストリームを使用できない理由を明確にさせてください。問題は、バッチを順番に処理する必要があることです。つまり、バッチを並行して実行することはできません (もちろん、複数のストリームで実行することは可能でした)。ただし、各バッチを処理するときに、次のバッチのデータを事前にロードして、データ転送を隠すことができます。ロバートの例を使用するには:

cudaMemcpyAsync( <data for batch1>, dataStream);
cudaMemcpyAsync( <data for batch2>, dataStream);
kernelForBatch1<<<..., opsStream>>>(...);
kernelForBatch2<<<..., opsStream>>>(...);
4

1 に答える 1

4

cudaStreamWaitEvent API 関数を使用するなど、cuda イベントを使用してストリームを同期することができます。ただし、すべてのデータ コピーを 1 つのストリームに配置し、すべてのカーネル呼び出しを別のストリームに配置するという考えは、ストリームの賢明な使用法ではない場合があります。

単一のストリーム内で発行された cuda 関数 (API 呼び出し、カーネル呼び出し) は順番に実行されることが保証され、そのストリーム内の cuda 関数は、そのストリーム内の以前のすべての cuda アクティビティが完了するまで開始されません (次のような呼び出しを使用している場合でも)。 cudaMemcpyAsync...)

したがって、ストリームは、必要なデータがコピーされるまでカーネル呼び出しが開始されないようにするメカニズムを既に提供しています。データコピーの後に、そのカーネル呼び出しを同じストリームに入れるだけです。

このようなものが同期を処理するはずです:

cudaMemcpyAsync( <data for kernel1>, stream1);
cudaMemcpyAsync( <data for kernel2>, stream2);
kernel1<<<..., stream1>>>(...);
kernel2<<<..., stream2>>>(...);
cudaMemcpyAsync( <data from kernel1>, stream1);
cudaMemcpyAsync( <data from kernel2>, stream2);

上記の呼び出しはすべて非同期であるため、非同期実行の他の要件 (固定メモリの使用など) を満たしていると仮定すると、上記の呼び出しはすべて「キューに入れられ」、すぐに返されます。ただし、 は、前に発行されたが完了kernel1する前に開始されないことが保証されており、および のデータ転送も同様です。cudaMemcpyAsyncstream1kernel2stream2

上記のアクティビティを別の CPU スレッドに分割する理由もわかりません。それは不必要に物事を複雑にします。単一のデバイスを管理する最も問題のない方法は、単一の CPU スレッドから行うことです。

于 2013-07-19T21:40:43.990 に答える