マルチ 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 と何らかの「コンテキスト移行」を使用) はありますか?