3

システム内の他の粒子によって加えられる粒子にかかる総力を計算するOpenCLカーネルと、粒子の位置/速度を統合する別のカーネルがあります。これらのカーネルを複数のGPUに並列化して、基本的に各GPUにある程度のパーティクルを割り当てたいと思います。ただし、このカーネルを複数回実行する必要があり、各GPUからの結果が相互に使用されます。それについてもう少し説明させてください。

GPU 0にパーティクル0があり、GPU 1にパーティクル1があるとします。パーティクル1にかかる力と同様に、パーティクル0にかかる力が変更され、それに応じてインテグレータによってそれらの位置と速度が変更されます。次に、これらの新しい位置を各GPUに配置する必要があり(両方のGPUは、パーティクル0とパーティクル1の両方がどこにあるかを知る必要があります)、これらの新しい位置を使用して、次のステップで各パーティクルにかかる力を計算します。積分器。その結果は力などの計算に使用されます。基本的に、力の計算が実行されるまでに、すべてのバッファーに同じ情報が含まれている必要があります。

したがって、問題は次のとおりです。各GPUに異なるバッファーがある場合、GPU間でバッファーを同期するための最良の方法は何ですか?最後の質問のように、並列処理を維持したい場合は、単一の共有バッファーを持つことはできません(ただし、共有バッファーを作成し、複数のGPUを維持する方法がある場合は、それで十分です)。各ステップで結果をコピーすると、GPU間でアルゴリズムを並列化する価値があるよりも速度が低下するのではないかと思います。

私はこのスレッドを見つけましたが、答えはあまり明確ではなく、すべてのGPUの単一のバッファーにのみ適用されました。具体的には、Nvidia GPU(より具体的には、Tesla M2090)について知りたいです。

編集:実際、Khronosフォーラムのこのスレッドによると、OpenCLワーキンググループの代表者は、共有コンテキスト上の単一のバッファーが実際に複数のGPUに分散され、それぞれがメモリ内に最新の情報を持っていることを確認すると述べています。ただし、NvidiaGPUではその動作は見られません。プログラムをバックグラウンドで実行しているときに使用するwatch -n .5 nvidia-smiと、あるGPUのメモリ使用量がしばらく増加し、次に別のGPUのメモリ使用量が増加する間に減少します。これで私を正しい方向に向けることができる人はいますか?多分それは彼らの実装だけですか?

4

1 に答える 1

4

実装に問題があるようです。

共有メモリで複数のGPUを利用するいくつかの異なる方法を示すSIGGRAPHからの素晴らしいプレゼンテーションがあります。スライドはこちらです。

現在の設定では、複数のコマンドキューを持つ複数のデバイスを含む単一のコンテキストがあると思います。あなたがしていることのために、これはおそらく正しい道です。

OpenCL 1.2仕様の付録Aには、次のように書かれています。

OpenCLメモリオブジェクト[...]はコンテキストを使用して作成され、同じコンテキストを使用して作成された複数のコマンドキュー間で共有できます。

さらに遠く:

アプリケーションは、ホストプロセッサ上のスレッド間で適切な同期を実装して、複数のスレッドで複数のコマンドキューが作成されているときに、共有オブジェクトの状態の変更が正しい順序で行われるようにする必要があります[...]共有オブジェクトの状態に変更します。

したがって、粒子の位置と速度を計算するカーネルは、粒子間の力を計算するカーネルに依存する必要があるように思われます。あなたはすでにそれを知っているようですね。

あなたの質問の観点から物事をもっと言えば:

各GPUに異なるバッファーがある場合、GPU間でバッファーを同期するための最良の方法は何ですか?

...答えは「バッファを分離しないでください」だと思います。そのオブジェクトを同じコンテキストから取得cl_memすることにより、2つのデバイス間で同じオブジェクトを使用します。cl_mem

データが実際に存在する場所については...ご指摘のとおり、これは実装によって定義されます(少なくとも仕様からわかる限り)。おそらく、データがどこにあるかを気にする必要はなく、両方のコマンドキューからデータにアクセスするだけです。

これにより、パフォーマンスに深刻な問題が生じる可能性があることを認識しています。実装は進化して改善される可能性が高いため、現在の仕様に従ってコードを記述すれば、将来的にはより適切に実行される可能性があります。

より良い(または最も異なる)バッファ共有動作を得るために試すことができるもう1つのことは、パーティクルデータをマップにすることです。

それが助けになるなら、私たちのセットアップ(デュアルC2070を備えたノードの束)はかなり最適にバッファを共有しているようです。データが1つのデバイスにのみ保持される場合もあれば、両方の場所にデータが存在する場合もあります。

全体として、ここでの答えは、仕様が提供する最善の方法でそれを実行し、実装の観点から最良のものを期待することだと思います。

お役に立てば幸いです、

ライアン

于 2012-07-25T20:38:01.493 に答える