web-dev-qa-db-ja.com

cudaカーネル呼び出しは同期または非同期ですか

カーネル起動を使用して異なるブロックを同期できることを読みました。つまり、すべてのブロックが操作2に進む前に操作1を完了させたい場合は、操作1を1つのカーネルに配置し、操作2を別のカーネルに配置する必要があります。このようにして、ブロック間のグローバル同期を実現できます。ただし、cuda cプログラミングガイドには、カーネル呼び出しは非同期であると記載されています。 CPUは最初のカーネル呼び出しが終了するのを待たないため、CPUは1番目が終了する前に2番目のカーネルを呼び出すこともできます。ただし、これが当てはまる場合、カーネル起動を使用してブロックを同期することはできません。どこが悪いのか教えてください

24
Programmer

カーネル呼び出しはCPUの観点から非同期であるため、2つのカーネルを連続して呼び出すと、最初のカーネルが終了するのを待たずに2番目のカーネルが呼び出されます。これは、制御がすぐにCPUに戻ることを意味するだけです。

GPU側では、カーネルを実行するために異なるストリームを指定していない場合、それらは呼び出された順序で実行されます(ストリームを指定しない場合、両方ともデフォルトストリームに移動し、シリアルに実行されます)。最初のカーネルが終了した後でのみ、2番目のカーネルが実行されます。

この動作は、カーネルの同時実行をサポートする計算機能2.xを備えたデバイスに有効です。他のデバイスでは、カーネル呼び出しがまだ非同期であっても、カーネルの実行は常に順次です。

すべてのCUDAプログラマーが読むべきセクション3.2.5のCUDACプログラミングガイドを確認してください。

34
jmsu

受け入れられた答えは必ずしも正しいとは限りません。

ほとんどの場合、カーネルの起動は非同期です。ただし、次の場合は同期です。そして、それらは人々によって簡単に無視されます。

  • 環境変数CUDA_LAUNCH_BLOCKINGは1に等しい。
  • 同時カーネルプロファイリングを有効にせずに、プロファイラー(nvprof)を使用する
  • ページロックされていないホストメモリを含むmemcpy。

プログラマーは、CUDA_LAUNCH_BLOCKING環境変数を1に設定することにより、システムで実行されているすべてのCUDAアプリケーションのカーネル起動の非同期性をグローバルに無効にできます。この機能はデバッグ目的でのみ提供され、本番ソフトウェアを確実に実行する方法として使用しないでください。

同時カーネルプロファイリングが有効になっていない限り、ハードウェアカウンターがプロファイラー(Nsight、Visual Profiler)を介して収集される場合、カーネルの起動は同期的です。非同期メモリコピーは、ページロックされていないホストメモリを含む場合にも同期されます。

NVIDIA CUDAプログラミングガイドから( http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#concurrent-execution-Host-device )。

8
pgplus1628