1

マルチ GPU フレームワーク (Windows 上) があり、特定の GPU で実行される「ジョブ」(実行する GPU も指定する) を指定できます。現在、フレームワークの起動時に GPU ごとに 1 つの「ワーカー スレッド」を作成し、ジョブが処理されるのを待つというアプローチをとっています。具体的には、 https: //devtalk.nvidia.com/search/more/sitecommentsearch/GPUworker/ の「GPUWorker」クラスを使用します。

これまでのところ問題なく動作しますが、パフォーマンスに関連する重大な欠点がいくつかあります。

  • 私たちのフレームワークでは、GPU が実際にはジョブの時間の 50% しか使用されていない場合でも、特定の GPU が「ジョブ」の全時間にわたってロックされます。ジョブの粒度が非常に粗いことに注意してください。たとえば、「オプティカル フローの計算を行う」には、50 ~ 100 ミリ秒かかることがあります。

  • GPU をロックしない特定の「非同期」ジョブ (非同期ホスト デバイス コピーなど) を指定することはできません。

だから私は今、その問題に対する「より良い」戦略について考えています。私の考えは次のとおりです。「起動」された新しいジョブごとに、新しい「一時的な」CPU スレッドを作成します。次に、CPU スレッドは、作業が行われる GPU のデバイス番号を (「cudaSetDevice」を介して) 設定します。この時点でも (私にとっては透過的に) Cuda コンテキストが作成されると思います。正しいデバイスを確認した後、ジョブの「doWork」関数が CPU スレッドによって実行されます。ジョブが同期または非同期で実行されるかどうかに応じて、 「結合」が完了した (CPU スレッドの完了を待っている) かどうか。

いくつか質問があります。

  • それは「良い」戦略ですか、それともこれを処理するより良い方法を誰かが知っていますか? もちろん、それはスレッドセーフな戦略でなければなりません。

  • 私の提案した戦略では、新しい CPU スレッドの作成と Cuda コンテキストの (隠された) 作成の典型的なオーバーヘッド (ミリ秒単位) はどれくらいですか? さらに、たとえば Cuda コンテキストの作成が重要な場合、このオーバーヘッドを削減する方法 (たとえば、cuda デバイス API と何らかの「コンテキスト移行」を使用) はありますか?

4

1 に答える 1