3

最近、MPI を使用してシミュレーション プログラムを並列化し、高速化しました。私が採用した方法は、非常に時間がかかるが並列化が容易な 1 つの関数を書き直すことでした。

非 MPI プログラムの単純化されたモデルは次のとおりです。

int main( int argc, char* argv[] ){
    // some declaration here
    Some_OBJ.Serial_Function_1();
    Some_OBJ.Serial_Function_2();
    Some_OBJ.Serial_Function_3(); 
    return 0;
}

私のMPIバージョンは、

#include "mpi.h"
int main( int argc, char* argv[] ){
    // some declaration here
    MPI_Init( NULL, NULL );
    Some_OBJ.Serial_Function_1();
    Some_OBJ.Parallel_Function_2(); // I rewrite this function to replace Some_OBJ.Serial_Function_2();
    Some_OBJ.Serial_Function_3(); 
    MPI_Finalize();
    return 0;
}

非 MPI コードを mpi_simulation などの新しいフォルダーにコピーし、mpi 関数を追加して、メイン ファイルを . 動作しますが、非常に不便です。OBJ.Serial_Function_1() などの一部の関数を更新する場合、定数を変更するだけでも、注意してコードをコピーする必要があります。これらのバージョンのプログラムには、まだ若干の違いがあります。それらを順守するのに疲れました。

そのため、MPI プログラムを MPI 以外のバージョンに依存させる方法があるかどうか、私は迷っています。そうすれば、私のリビジョンをそれらの両方に安全かつ便利に簡単に適用できます。

ありがとう。

更新私はついにharaldklの提案を採用しました。この方法は、次のように、MPI インターフェイスを使用するすべての関数を囲むマクロを定義することです。

#ifdef USE_MPI
void Some_OBJ::Parallel_Function_2(){
  // ...
}
#endif

MPI を自動的に初期化するために、MPI_plugin というシングルトンを定義します。

#ifdef USE_MPI
class MPI_plugin{
private:
    static MPI_plugin auto_MPI;
    MPI_plugin(){
      MPI_Init( NULL, NULL );
    }
public:
    ~MPI_plugin(){
      MPI_Finalize();
    }
};
MPI_plugin::MPI_plugin auto_MPI;
#endif

MPI バージョンをコンパイルするときに、main.cpp に MPI_plugin.h を含めることで、main.cpp に MPI_Init() と MPI_Finalize() を追加する必要がなくなります。最後のステップは、メイクファイルに PHONY ターゲット「mpi」を追加することです。

CPP := mpic++
OTHER_FLAGS := -DUSE_MPI
.PHONY: mpi
mpi: ${MPI_TARGET}
...

同じ問題を抱えている方の参考になれば幸いです。

4

1 に答える 1

1

問題を解決する 1 つの方法は、(まだインストールされていない場合) 利用可能な「ダミー MPI」ライブラリの 1 つをインストールすることです。コードが 1 つの MPI プロセスで正しく実行される限り (そのように記述されているはずです)、ダミーの MPI ライブラリにリンクされたときに正しく実行されるはずです。ダミーの MPI ライブラリに慣れていない場合は、Google.

于 2012-04-29T17:10:05.567 に答える