77

関数の呼び出しがcudaDeviceSynchronize本当に必要になるのはいつですか?

私が CUDA のドキュメントから理解している限り、CUDA カーネルは非同期であるため、cudaDeviceSynchronizeカーネルを起動するたびに呼び出す必要があるようです。cudaDeviceSynchronizeただし、時間測定の前の 1 つを除いて、 の有無にかかわらず同じコード (ニューラル ネットワークのトレーニング) を試しました。同じ結果が得られますが、速度は 7 ~ 12 倍 (行列のサイズによって異なります) であることがわかりました。

cudaDeviceSynchronizeしたがって、問題は、時間測定以外に使用する理由があるかどうかです。

例えば:

  • を使用して GPU からホストにデータをコピーする前に必要cudaMemcpyですか?

  • 次のような行列乗算を行う場合

    C = A * B
    D = C * F
    

cudaDeviceSynchronize両方の間に入れるべきですか?

私の実験ではそうではないようです。

なぜ はcudaDeviceSynchronizeプログラムをそんなに遅くするのですか?

4

4 に答える 4

69

CUDA カーネルの起動は非同期ですが、1 つのストリームに配置されたすべての GPU 関連のタスク (これがデフォルトの動作です) は順次実行されます。

たとえば、

kernel1<<<X,Y>>>(...); // kernel start execution, CPU continues to next statement
kernel2<<<X,Y>>>(...); // kernel is placed in queue and will start after kernel1 finishes, CPU continues to next statement
cudaMemcpy(...); // CPU blocks until memory is copied, memory copy starts only after kernel2 finishes

したがって、あなたの例では、必要はありませんcudaDeviceSynchronize。ただし、どのカーネルがエラーを引き起こしたかを検出するデバッグに役立つ場合があります (存在する場合)。

cudaDeviceSynchronize速度が遅くなる可能性がありますが、7-12x は多すぎるようです。時間の測定に問題があるか、カーネルが非常に高速で、明示的な同期のオーバーヘッドが実際の計算時間に比べて非常に大きい可能性があります。

于 2012-08-09T18:22:48.273 に答える
18

cudaDeviceSynchronize()を使用するのが適切な状況の 1 つは、いくつかcudaStreamの を実行していて、それらに何らかの情報を交換させたい場合です。これの実際のケースは、量子モンテカルロ シミュレーションでの並列テンパリングです。この場合、すべてのストリームが一連の命令の実行を完了し、メッセージを相互に渡し始める前に結果を取得したことを確認する必要があります。このコマンドを使用するとプログラムが非常に遅くなる理由は、cudaDeviceSynchronize()続行する前に、デバイス上のすべてのストリームで以前に発行されたすべてのコマンドが終了するまでプログラムを強制的に待機させます (CUDA C プログラミング ガイドより)。あなたが言ったように、カーネルの実行は通常非同期であるため、GPU デバイスがカーネルを実行している間、CPU は待機する代わりに、他のコマンドを処理したり、デバイスにさらに命令を発行したりできます。ただし、この同期コマンドを使用すると、すべての GPU 作業が完了するまで CPU が強制的にアイドル状態になり、他の処理が行われなくなります。デバイス コードの非同期実行 (1 つのストリームまたは多数のストリーム) が原因で、一見「ランダムな」時間にセグメンテーション違反が発生する可能性があるため、この動作はデバッグ時に役立ちます。cudaDeviceSynchronize()続行する前にストリームのカーネル/memcpys が完全であることをプログラムに強制します。これにより、不正なアクセスがどこで発生しているかを簡単に見つけることができます (同期中にエラーが表示されるため)。

于 2012-08-09T18:20:20.807 に答える
12

GPU でデータの処理を開始する場合、通常はカーネル呼び出しを行います。そうすることで、デバイス (GPU) は、あなたが指示したことを何でも実行し始めます。ただし、ホスト (CPU) 上の通常のシーケンシャル プログラムとは異なり、プログラム内の次のコード行を実行し続けます。cudaDeviceSynchronize は、開始したすべてのスレッドの実行がデバイス (GPU) で完了するまでホスト (CPU) を待機させるため、プログラムは通常のシーケンシャル プログラムであるかのように続行します。

小規模で単純なプログラムでは、GPU を使用して計算を行う場合、通常は cudaDeviceSynchronize を使用して、結果を要求する CPU と計算を終了する GPU の間のタイミングの不一致を回避します。cudaDeviceSynchronize を使用すると、プログラムのコーディングが非常に簡単になりますが、大きな欠点が 1 つあります。GPU が計算を行っている間、CPU は常にアイドル状態です。したがって、高性能コンピューティングでは、GPU が完了するのを待つ間、CPU に計算を行わせるように努力することがよくあります。

于 2014-01-20T16:45:14.303 に答える