2

私は3つの機能と4つのコアを持っています。MPI と C++ を使用して新しいスレッドで各関数を実行したい

int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
size--;
if (rank == 0)
{
    Thread1();
}
else 
{
    if(rank == 1)
    {
        Thread2();
    }
    else
    {
        Thread3();
    }
}
MPI_Finalize();

ただし、Thread1() だけを実行します。コードをどのように変更する必要がありますか?

ありがとう!

4

2 に答える 2

6

variable の現在の値を画面に出力するsizeと (おそらくデクリメントせずに)、 が見つかります1。つまり、「1実行中のプロセスがあります」。

コンパイルしたコードを間違った方法で実行している可能性があります。mpirun (またはmpiexec、MPI 実装に応じて) を使用して実行することを検討してください。つまり、

 mpirun -np 4 ./MyCompiledCode

この-npパラメーターは、開始するプロセスの数を指定します (そうすると、 MPI_Comm_size予想どおり 4 になります)。


ただし、現在、C++ のために明示的に何も使用していません。などの MPI の C++ バインディングを検討できますBoost.MPI


教えていただいたコードを少し加工しました。私はそれを少し変更して、この 動作するmpi コードを生成しました (大文字で必要な修正をいくつか提供しました)。

ご参考までに:

  • コンパイル (gcc、mpich で):

     $ mpicxx -c mpi1.cpp 
     $ mpicxx -o mpi1 mpi1.o
    
  • 実行

    $ mpirun -np 4 ./mpi1
    
  • 出力

    size is 4
    size is 4
    size is 4
    2 function started.
    thread2
    3 function started.
    thread3
    3 function ended.
    2 function ended.
    size is 4
    1 function started.
    thread1
    1 function ended.
    

stdoutめちゃくちゃになる可能性があることに注意してください。

コードを正しい方法でコンパイルしていますか?

于 2012-10-28T13:00:42.210 に答える
2

問題は、MPI がコンソール入力を多くのプロセスにフィードする方法を提供せず、 rank を持つプロセスにのみ提供すること0です。の最初の 3 行のためmain:

int main(int argc, char *argv[]){

    int oper;
    std::cout << "Enter Size:";
    std::cin >> oper;           // <------- The problem is right here

    Operations* operations = new Operations(oper);
    int rank, size;
    MPI_Init(&argc, &argv);
    int tid;
    MPI_Comm_rank(MPI_COMM_WORLD, &tid);
    switch(tid)
    {

0取得できないコンソール入力を待機しているブロックをランク付けする以外のすべてのプロセス。main関数の先頭を次のように書き換える必要があります。

int main(int argc, char *argv[]){

    int oper;

    MPI_Init(&argc, &argv);
    int tid;
    MPI_Comm_rank(MPI_COMM_WORLD, &tid);

    if (tid == 0) {
       std::cout << "Enter Size:";
       std::cin >> oper;
    }
    MPI_Bcast(&oper, 1, MPI_INT, 0, MPI_COMM_WORLD);

    Operations* operations = new Operations(oper);
    switch(tid)
    {

次のように動作します: ランクのみ0がプロンプトを表示し、コンソール入力を に読み込みますoperoper次に、ランクからの値のブロードキャスト0が実行され、他のすべてのプロセスが正しい値を取得し、Operationsオブジェクトを作成してから、適切な関数に分岐します。

于 2012-10-29T13:39:08.287 に答える