21

私のunix/windows C ++アプリは、MPIを使用してすでに並列化されています。ジョブはN cpusに分割され、各チャンクは並列で実行され、非常に効率的で、非常に高速なスケーリングで、ジョブは正しく実行されます。

ただし、一部のデータは各プロセスで繰り返され、技術的な理由から、このデータをMPIで簡単に分割することはできません(...)。例えば:

  • 5 Gbの静的データ、各プロセスにまったく同じものがロードされます
  • MPIで分散できる4Gbのデータは、使用されるCPUが多いほど、このCPUあたりのRAMは小さくなります。

4 CPUジョブでは、これは少なくとも20GbのRAM負荷を意味し、メモリの大部分は「無駄」になります。これはひどいことです。

全体的な負荷を減らすために共有メモリを使用することを考えています。「静的」チャンクは、コンピューターごとに1回だけロードされます。

したがって、主な質問は次のとおりです。

  • ノード上でメモリを共有するための標準的なMPIの方法はありますか? ある種のすぐに利用できる+無料のライブラリ?

    • そうでない場合は、boost.interprocessMPI呼び出しを使用して、ローカル共有メモリ識別子を配布します。
    • 共有メモリは、各ノードの「ローカルマスター」によって読み取られ、共有読み取り専用になります。変更されないため、セマフォ/同期の種類は必要ありません。
  • パフォーマンスの低下や注意すべき特定の問題はありますか?

    • (「文字列」や過度に奇妙なデータ構造はありません。すべてを配列と構造ポインターにまとめることができます)
  • ジョブはPBS(またはSGE)キューイングシステムで実行されます。プロセスがクリーンでない出口の場合、それらがノード固有の共有メモリをクリーンアップするかどうか疑問に思います。

4

8 に答える 8

9

ハイパフォーマンスコンピューティング(HPC)でますます一般的になっているアプローチの1つは、ハイブリッドMPI/OpenMPプログラムです。つまり、N個のMPIプロセスがあり、各MPIプロセスにはM個のスレッドがあります。このアプローチは、共有メモリマルチプロセッサノードで構成されるクラスタにうまく対応します。

このような階層型並列化スキームに変更するには、明らかに多少の侵襲的な変更が必要です。OTOHを適切に実行すると、レプリケートされたデータのメモリ消費を削減するだけでなく、コードのパフォーマンスとスケーラビリティを向上させることができます。

MPIの実装によっては、すべてのスレッドからMPI呼び出しを実行できる場合とできない場合があります。これは、MPI_Init()の代わりに呼び出す必要があるMPI_Init_Thread()関数の引数requiredと引数によって指定されます。provided可能な値は次のとおりです

{MPI_THREAD_SINGLE}
    1つのスレッドのみが実行されます。
{MPI_THREAD_FUNNELED}
    プロセスはマルチスレッドである可能性がありますが、メインスレッドのみがMPI呼び出しを行います(すべてのMPI呼び出しはメインスレッドに「ファネル」されます)。
{MPI_THREAD_SERIALIZED}
    プロセスはマルチスレッドであり、複数のスレッドがMPI呼び出しを行う場合がありますが、一度に1つだけです。MPI呼び出しは2つの異なるスレッドから同時に行われることはありません(すべてのMPI呼び出しは「シリアル化」されます)。
{MPI_THREAD_MULTIPLE}
    複数のスレッドが制限なしでMPIを呼び出すことができます。

私の経験では、Open MPIのような最新のMPI実装は、最も柔軟なMPI_THREAD_MULTIPLEをサポートしています。古いMPIライブラリ、またはいくつかの特殊なアーキテクチャを使用している場合は、さらに悪化する可能性があります。

もちろん、OpenMPを使用してスレッド化を行う必要はありません。これは、HPCで最も人気のあるオプションです。たとえば、Boostスレッドライブラリ、Intel TBBライブラリ、またはストレートpthreadやwindowsスレッドを使用できます。

于 2010-01-06T00:52:54.163 に答える
8

私はMPIを使用していませんが、他のスレッド/プロセスなどが同じマシン上にあるか異なるマシン上にあるかを隠す他のIPCライブラリのように、共有メモリを保証することはできません。はい、そのマシンが共有メモリ自体を提供していれば、同じマシン上の2つのノード間の共有メモリを処理できます。ただし、複雑なコヒーレンシの問題が発生するため、異なるマシン上のノード間でメモリを共有しようとすることは、せいぜい非常に困難です。私はそれが単に実装されていないことを期待します。

実際には、ノード間でメモリを共有する必要がある場合、最善の策はMPIの外部でそれを行うことです。boost.interprocessさまざまなノードが共有メモリにきめ細かい変更を加えている状況を説明していないため、スタイルの共有メモリを使用する必要はないと思います。読み取り専用またはパーティション化されています。

Johnとdeusの回答は、ファイルにマップする方法をカバーしています。これは、5 Gb(ギガビット?)の静的データに対して確実に実行したいことです。CPUごとのデータは同じように聞こえます。各ノードにメッセージを送信して、ファイルのどの部分を取得する必要があるかを通知する必要があります。OSは、仮想メモリから物理メモリ、ファイルへのマッピングを処理する必要があります。

クリーンアップに関しては...共有メモリのクリーンアップは行わないと思いmmapますが、プロセスがクリーンアップされるとファイルが閉じられる(メモリマッピングが解放される)ため、edファイルをクリーンアップする必要があります。CreateFileMapping警告などが何であるかわかりません。

実際の「共有メモリ」(つまりboost.interprocess)は、プロセスが停止してもクリーンアップされません。可能であれば、プロセスを強制終了して、何が残っているかを確認することをお勧めします。

于 2009-12-27T07:21:27.550 に答える
2

MPI-2を使用すると、MPI_PutやMPI_Getなどの関数を介してRMA(リモートメモリアクセス)を利用できます。MPIインストールでこれらの機能がサポートされている場合、これらの機能を使用すると、プログラムの総メモリ消費量を確実に削減できます。コストはコーディングの複雑さを増しますが、それは並列プログラミングの楽しみの一部です。繰り返しになりますが、MPIの領域にとどまります。

于 2009-12-29T10:05:14.560 に答える
1

MPI-3は共有メモリウィンドウ(例を参照MPI_Win_allocate_shared())を提供します。これにより、追加の依存関係なしにノード上の共有メモリを使用できます。

于 2018-03-26T06:50:10.197 に答える
0

私はUNIXについてあまり知りませんし、MPIが何であるかわかりません。しかし、Windowsでは、説明しているのはファイルマッピングオブジェクトと完全に一致することです。

このデータがロードされる.EXEまたは.DLLに埋め込まれている場合、すべてのプロセス間で自動的に共有されます。プロセスのティアダウンは、クラッシュの結果であっても、データのリークや解放されていないロックを引き起こすことはありません。ただし、9Gb.dllは少し不自然に聞こえます。したがって、これはおそらくあなたにとってはうまくいきません。

CreateFileMappingただし、データをファイルに入れて、その上に置くことはできますMapViewOfFile。マッピングは読み取り専用にすることができ、ファイルのすべてまたは一部をメモリにマッピングできます。すべてのプロセスは、同じ基になるCreateFileMappingオブジェクトにマップされているページを共有します。マップ解除ビューを閉じてハンドルを閉じることをお勧めしますが、そうでない場合は、OSが分解時に自動的に行います。

x64を実行していない限り、5Gbファイルを単一のビューにマップすることはできません(または2Gbファイルでも1Gbが機能する可能性があります)。しかし、これがすでに機能していることについて話していることを考えると、あなたはすでにx64のみであると推測しています。

于 2009-12-26T21:27:09.563 に答える
0

静的データをファイルに保存する場合は、UNIXでmmapを使用して、データにランダムアクセスすることができます。データの特定のビットにアクセスする必要があるときに、データがページインされます。あなたがする必要があるのは、ファイルデータの上にバイナリ構造をオーバーレイすることだけです。これは、前述のCreateFileMappingおよびMapViewOfFileと同等のUNIXです。

ちなみに、glibcは、mallocを呼び出して1ページを超えるデータを要求するときにmmapを使用します。

于 2009-12-26T22:50:34.310 に答える
0

SHUTでMPIを使ったプロジェクトがいくつかありました。

私が知っているように、MPIを使用して問題を分散する方法はたくさんあります。共有メモリを必要としない別の解決策を見つけることができるかもしれません。私のプロジェクトは、7,000,000の方程式と7,000,000の変数を解くことでした。

あなたがあなたの問題を説明することができれば、私はあなたを助けようとします

于 2009-12-28T19:28:53.217 に答える
0

数年前にMPIを使用したとき、私は小さな問題に遭遇しました。

SGEがメモリマップトファイルを理解するかどうかはわかりません。beowulfクラスターに対して配布する場合は、コヒーレンシの問題が発生する可能性があります。マルチプロセッサアーキテクチャについて少しお話しいただけますか?

私のドラフトアプローチは、データの各部分が定義されたCPUによって所有されるアーキテクチャをセットアップすることです。2つのスレッドがあります。1つのスレッドはMPI双方向トーカーであり、もう1つのスレッドは結果を計算するためのものです。MPIとスレッドは常に一緒にうまく機能するとは限らないことに注意してください。

于 2010-01-06T01:15:56.650 に答える