cudaでの同期についてcudaのリファレンスマニュアルを読んだのですが、はっきりとはわかりません。たとえば、なぜ or を使用するのcudaDeviceSynchronize()
か__syncthreads()
? それらを使用しない場合、何が起こるか、プログラムは正しく動作しませんか? cudaMemcpy
とcudaMemcpyAsync
in actionはどう違いますか?
この違いを示す例を示すことができますか?
2 に答える
cudaDeviceSynchronize()
保留中の GPU アクティビティが完了するまで CPU アクティビティを待機させたい場合に、ホスト コード (つまり、CPU で実行中) で使用されます。多くの場合、これを明示的に行う必要はありません。単一のストリームに対して発行された GPU 操作は自動的にシリアル化され、cudaMemcpy()
固有のブロッキング デバイス同期が組み込まれているような他の操作もあります。ただし、コードのデバッグなど、その他の目的では、未処理のアクティビティをデバイスに強制的に終了させると便利な場合があります。
__syncthreads()
デバイス コード (つまり、GPU で実行中) で使用され、独立した並列操作 (要素ごとに 2 つのベクトルを一緒に追加するなど) を持つコードではまったく必要ない場合があります。ただし、一般的に使用される 1 つの例は、共有メモリを使用して動作するアルゴリズムです。このような場合、グローバル メモリから共有メモリに値をロードする必要があることがよくあります。実際の処理が発生する前に、スレッドブロック内の各スレッドが適切な共有メモリ ロケーションをロードする機会が必要です。この場合__syncthreads()
、処理が発生する前に使用して、共有メモリが完全に読み込まれるようにします。これはほんの一例です。 __syncthreads()
スレッドのブロック内で同期が必要な場合はいつでも使用できます。ブロック間の同期はできません。
cudaMemcpy
との違いcudaMemcpyAsync
は、非非同期バージョンの呼び出しはストリーム 0 に対してのみ発行でき、コピーが完了するまで呼び出し元の CPU スレッドをブロックすることです。非同期バージョンは、必要に応じてストリーム パラメーターを受け取ることができ、コピーが完了する前に、呼び出し元のスレッドにすぐに制御を返します。非同期バージョンは通常、非同期の同時実行が必要な状況で使用されます。
CUDA プログラミングに関する基本的な質問がある場合は、利用可能なウェビナーのいくつかを受講することをお勧めします。