最近、MPIを使用してシミュレーションプログラムを並列化してスピードアップしました。私が採用した方法は、非常に時間がかかるが、並列化が容易な1つの関数を書き換えることでした。はMPIバージョンと非MPIバージョンを便利な方法で維持します
次のように非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_simulationのようなものを私の非MPIコードをコピーmpi関数を追加し、メインファイルを改訂しました。それは動作しますが、非常に不便です。いくつかの関数、たとえばOBJ.Serial_Function_1()を更新する場合、定数を変更するだけでもコードを慎重にコピーする必要があります。これらのバージョンのプログラムにはまだ若干の違いがあります。私はそれらを守るために疲れていた。
MPIプログラムをMPI以外のバージョンに依存させる方法があれば、私の改訂版を安全かつ便利に両者に簡単に適用できるようにする方法があれば、私は歩き回ります。
ありがとうございました。
更新 私はついにハラルドクの提案を採用します。 MPI_plugin.h含ま
#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_plugin呼ばれるシングルトンを定義し、
#ifdef USE_MPI
void Some_OBJ::Parallel_Function_2(){
// ...
}
#endif
が自動的にMPIを初期化する: 方法は次のように、MPIインターフェースを使用するすべての機能を取り囲むようにマクロを定義することですMPIバージョンをコンパイルするときにmain.cppにMPI_Init()とMPI_Finalize()を追加しても、main.cppの私は生き残ることができます。 最後のステップは、メイクファイルに偽の目標「MPI」を追加することです:
CPP := mpic++
OTHER_FLAGS := -DUSE_MPI
.PHONY: mpi
mpi: ${MPI_TARGET}
...
私は同じ問題を満たしている人には、それが参考に願っています。
これを達成するために通常前処理が使用されますが、これは実行可能なオプションではありませんか? – haraldkl
コードの非並行バージョンが厳密に必要ですか? MPIのないマシンでコンパイルまたは実行されますか? – suszterpatt
はい、MPIをインストールして他のクラスタでタスクを実行する特権がないマシンで開発します。 – anecdote