2

関係するCPUがアドレス空間を共有しないように、Beowulfクラスター全体でいくつかのコードを並列化することを検討しています。外側のループで関数呼び出しを並列化したい。関数呼び出しには「重要な」副作用はありません(ただし、乱数ジェネレーターを使用したり、メモリを割り当てたりします)。

私はMPIのようなライブラリを見てきましたが、問題は、ノード間で複雑なオブジェクトグラフを渡すのが非常に簡単ではないように見えることです。私の関数への入力は、非常に複雑なオブジェクトグラフを指すthisポインターです。私の関数の戻り値は、別の複雑なオブジェクトグラフです。

言語に依存しないレベルで(私はDプログラミング言語で作業しており、ここで利用できるソリューションはほぼ確実ですが、作成するつもりです)、複雑なパスを通過する「典型的な」方法はありますかノード間の状態は処理されますか?理想的には、状態がどのようにコピーされるかの詳細を完全に抽象化し、呼び出しを通常の関数呼び出しのように見せたいと思います。問題の並列処理のレベルは非常に粗く、おそらく問題にならないため、ネットワークを介してこれだけの状態をコピーすることが特に効率的でないことは気にしません。

編集:複雑な状態を渡す簡単な方法がない場合、メッセージパッシングは通常どのように使用されますか?ネットワークを介したデータのコピーには粗粒度の並列処理が必要なように思えますが、粗粒度の並列処理では通常、1つの作業単位で多くの作業を実行できるように、複雑な状態を渡す必要があります。

4

4 に答える 4

3

私はかなりのMPIプログラミングを行っていますが、プロセス間で複雑な状態(あなたが説明しているように)を渡す典型的な方法を知りません。これが私があなたの問題についてどのように考えてきたかです、それはおそらくあなた自身の考えと一致します...

複雑なオブジェクトグラフは、メモリ内で、データのブロックと他のデータのブロックへのポインタによって表されていると思います。これは、グラフの通常の実装です。これらのCOGの1つを(省略形を作成するために)あるプロセスのアドレス空間から別のプロセスのアドレス空間に移動するにはどうすればよいでしょうか。ポインタがメモリアドレスである限り、あるアドレス空間のポインタは別のアドレス空間では役に立たないので、トランスポートのために中立的な形式に変換する必要があります(私は思いますか?)。

したがって、COGを送信するには、受信プロセスがローカルメモリアドレスを指すポインタを使用して、グラフのローカルバージョンを独自のアドレス空間に構築できる形式にする必要があります。これらのCOGをファイルに書き込んだことはありますか?もしそうなら、あなたはすでにそれを輸送することができるフォームを持っています。私はそれを提案するのは嫌ですが、プロセス間で通信するためにファイルを使用することもできます-そしてそれはDとMPIの組み合わせよりも扱いやすいかもしれません。あなたの選択 !

COGのファイル形式がない場合、隣接行列またはリストとして簡単に表すことができますか?言い換えれば、輸送のためのあなた自身の表現を考え出しますか?

ポインタベースから配列やレコードなどのより静的な構造に変換せずにプロセス間でCOGを渡すことができれば、私は非常に驚きます(ただし、学ぶことは喜ばしいことです)。

OPの編集に応じて編集します。MPIは、複雑な状態がポインターではなく値として表される場合、複雑な状態を渡す簡単な方法を提供します。組み込みまたはカスタマイズされたMPIデータ型のいずれかで複雑な状態を渡すことができます。他の答えの1つが示すように、これらは柔軟で有能です。プログラムが複雑な状態をMPIカスタムデータ型が処理できる形式で保持しない場合は、メッセージに適した表現にパック/アンパックする関数を作成する必要があります。それができれば、メッセージ呼び出しは(ほとんどの目的で)関数呼び出しのように見えます。

複雑な状態と並列処理の粗さを取り巻く問題については、私があなたを完全にフォローしているかどうかはわかりません。単一のプロセッサから十分なパフォーマンスを得ることができないため、通常、MPIプログラミングに頼ります(必要に応じて、この抜本的な一般化に参加してください)。待機によって遅延する計算に関してペナルティを支払うことはわかっています。通信については、そのペナルティを最小限に抑えるように努めていますが、最終的には、並列化のコストとしてペナルティを受け入れます。確かに、一部のジョブは小さすぎたり短すぎたりして並列化のメリットを享受できませんが、私たち(つまり並列計算担当者)が行うことの多くは、並列化を回避するには大きすぎて実行時間が長すぎます

于 2010-02-27T11:12:31.173 に答える
2

カスタムMPIデータ型を使用してすばらしいことを行うことができます。私は現在、いくつかのMPIプロセスが仮想空間の一部で粒子を追跡しているプロジェクトに取り組んでおり、粒子が1つのプロセスの領域から別の領域に交差する場合、それらのデータ(位置/速度/サイズなど)はネットワーク経由で送信されます。

私がこれを達成した方法は次のとおりです。

1)すべてのプロセスは、関連するすべての属性を含む単一のパーティクルのMPI Structデータ型と、パーティクルオブジェクトのベースアドレスと比較したメモリ内の変位を共有します。

2)送信時に、プロセスはパーティクルを格納するデータ構造を繰り返し、送信する必要のある各ブロックのメモリアドレスを書き留めてから、各ブロックの長さが1(上記のパーティクルの)であるHindexedデータ型を構築します。 datatype)であり、前に書き留めたメモリアドレスから始まります。結果のタイプのオブジェクトを1つ送信すると、必要なすべてのデータがタイプセーフな方法でネットワーク経由で送信されます。

3)受信側では、物事は少しトリッキーです。受信プロセスは、最初に「空白」のパーティクルを独自のデータ構造に挿入します。「空白」は、他のプロセスから受信されるすべての属性がデフォルト値に初期化されることを意味します。新しく挿入されたパーティクルのメモリアドレスが書き留められ、送信者と同様のデータ型がこれらのアドレスから作成されます。送信者のメッセージをこのタイプの単一のオブジェクトとして受信すると、タイプセーフな方法で、すべてのデータがすべての適切な場所に自動的に解凍されます。

この例は、(グラフのノード間にあるように)パーティクル間に関係がないという意味でより単純ですが、同様の方法でそのデータを送信できます。

上記の説明が明確でない場合は、それを実装するC++コードを投稿できます。

于 2010-03-04T15:03:31.993 に答える
2

質問が正しく理解できているかどうかわからないので、答えが間違っている場合はご容赦ください。私が理解していることから、MPIを使用して非PODデータ型を送信したいと考えています。

これを実行できるライブラリはBoost.MPIです。シリアル化ライブラリを使用して、非常に複雑なデータ構造でも送信します。ただし、落とし穴があります。Boost.Serializeがまだ認識していない複雑な構造を使用する場合は、データを自分でシリアル化するためのコードを提供する必要があります。

メッセージパッシングは通常、PODデータ型を送信するために使用されると思います。

これ以上のリンクを投稿することは許可されていないので、ここに含めたいものを示します。

PODの説明:www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html

シリアル化ライブラリ:www.boost.org/libs/serialization/doc

于 2010-03-04T15:38:04.493 に答える
0

それはあなたのデータの構成に依存します。オブジェクト内でポインタや自動メモリを使用する場合、それは困難になります。オブジェクトをメモリ内で連続するように編成できる場合は、メモリをバイトとして送信するか、レシーバーのオブジェクトタイプにキャストバックするか、オブジェクトのmpi派生型を定義するかの2つの選択肢があります。ただし、継承を使用すると、オブジェクトがメモリ内でどのように配置されるかにより、状況が複雑になります。

私はあなたの問題を知りませんが、あなたが手動でメモリを管理するならば、多分ARMCIを見ることができます。

于 2010-02-28T21:27:39.663 に答える