2012-08-14 5 views
7

を同期CUDAでは、多くのカーネルは、この質問は、CUDAを使用してに関連して、待ち時間/遅延

を実行するために、ストリーム多くの同期があるかどうかを確認するために cudaStreamSynchronize、 CudaDeviceSynchronize、 cudaThreadSynchronize、 ともcudaStreamQueryコマンドストリームは空です。

プロファイラを使用すると、これらの同期コマンドによってプログラムに大きな遅延が生じることがわかりました。できるだけ少ない同期コマンドを使用してこのレイテンシーを減らす手段を誰かが知っているかどうかは疑問でした。

最も効果的な同期方法を判断する数値もあります。それはアプリケーションで使用されている3つのストリームを考慮し、2つは、私は2つのcudaStreamSyncsを使用する必要がありますか私はダウンストリームを開始するために完了する必要がありますか、わずか1つのcudaDeviceSyncは、

+1

cudaThreadSynchronizeは推奨されていません。 –

答えて

8

同期方法の主な違いは、「ポーリング」と「ブロック」です。

「ポーリング」は、ドライバがGPUを待つためのデフォルトのメカニズムで、32ビットのメモリ位置がGPUによって書き込まれる特定の値に達するのを待ちます。待機が解決された後、待ち時間をより早く返すかもしれませんが、待機中に、そのメモリ位置を見てCPUコアを焼き付けます。

cudaDeviceScheduleBlockingSynccudaSetDeviceFlags()を呼び出すか、cudaEventBlockingSynccudaEventCreate()を呼び出して、ブロックすることができます。ブロッキングウェイトは、ドライバがDMAコマンドバッファにコマンドを挿入し、バッファ内の先行するコマンドがすべて実行されたときに割り込みを通知します。ドライバは、割り込みをWindowsイベントまたはLinuxファイルハンドルにマップして、デフォルトのポーリング方法と同様にCPUを絶えず焼き付けることなく同期コマンドを待機させることができます。

クエリは、基本的に、ポーリング待機に使用される32ビットのメモリ位置の手動チェックです。ほとんどの状況で、彼らは非常に安いです。しかし、ECCを有効にすると、クエリーはカーネルモードに入り、ECCエラーがないかどうかをチェックします。 Windowsでは、保留中のコマンドはドライバにフラッシュされます(カーネルサンクが必要です)。

+0

ポーリングとブロックの違いは、ポーリングがCPU時間を消費し、ブロックがブロックされないということです。しかし、同期が発生するのにかかる時間に差はない。 CPUによって実行されるべき作業がない状況では、それらは同じことに減少する。あれは正しいですか ? – shadow

+0

割り込み処理によってレイテンシが追加されるため、時差が生じることがあります。したがって、ポーリング時にCPUを消費しないことと引き換えに、解決される待ち時間とスレッドがブロック解除されるまでの時間が長くなるという形で支払います。 – ArchaeaSoftware

+0

しかし 'cudaDeviceScheduleBlockingSync'と' cudaDeviceScheduleYield'の違いは何ですか? 「cudaDeviceScheduleYield」と書かれているように、「デバイスからの結果を待っているときにスレッドを生成するようCUDAに指示します。これにより、デバイスの待機時に待ち時間が長くなりますが、デバイスと並行して処理を実行するCPUスレッドのパフォーマンスが向上します。すなわちスピン**のCPUを燃やさずに結果**を待つ、すなわち「ブロッキング」。また、 'cudaDeviceScheduleBlockingSync'もスピンのCPUを燃やすことなく結果を待ちます。しかし違いは? – Alex

関連する問題