1

私はMPIがどのように機能するかについての直感を得ようとしています。したがって、私は小さな例から始めました:

...
MPI_Comm_rank(MPI_COMM_WORLD, &tid);
MPI_Comm_size(MPI_COMM_WORLD, &nthreads);

int message = 2;

if(tid != 0)
{
    MPI_Recv(&rec, 1, MPI_INT, tid-1, 0, MPI_COMM_WORLD, &status);
    printf("Process %i receive %i\n", tid, rec);
}

if(tid != nthreads-1)
{
    message++;
    printf("Process %i sends %i\n", tid, message);
    MPI_Send(&message, 1, MPI_INT, tid+1, 0, MPI_COMM_WORLD);
}
...

それは3を超えて増加しているように見えるという事実にもかかわらず、それはうまく機能messageします。それはなぜですか?

4

3 に答える 3

2

MPIランクはスレッドではなく、MPIで言えば「ランク」、つまり処理要素ですが、一般的にはプロセスです。

これは通常は些細なことですが、ここでは実際には根本的な混乱を反映していると思います。OpenMP(たとえば)の場合、次のコードがあります

int message = 0;

#pragma omp parallel default(none) shared(message)
{
   int tid = omp_get_thread_num();
   if (tid != nthreads-1) {
       #pragma omp atomic
       message++;
   }
}

次に、並列セクションの最後で、メッセージは実際にはOMP_NUM_THREADS-1何回もインクリメントされます。

しかし、MPIはスレッド化されていません。mpiexecまたはを使用してプログラムを起動するとmpirun、n個のタスクが起動され、それぞれが独自のプロセスでまったく同じプログラムを実行します。たとえば、共有変数はありません。特に、各タスクには独自の変数messageがあり、その変数は上記のコードスニペットで最大1回インクリメントmessageされます。つまり、投稿されたコードの最後では常に2または3になります。

于 2012-12-19T21:59:51.613 に答える
2

mpirun -np Nコマンドは、スレッドを使用Nする1つのプロセスではなく、MPIプロセスを開始します。N各プロセスには変数がmessageあり、各プロセスには2に設定された独自の変数があります。次の0番目のプロセスは、それmessage == 3を1番目のプロセスに送信します。その後、1番目のプロセスが自分自身message == 3を送信し、2番目のプロセスがそれをキャッチします...

于 2012-12-19T22:00:33.083 に答える
1

私はあなたが望むことは次のコードによって達成できると強く思います:

int message = 2;

if(tid != 0)
{
   MPI_Recv(&message, 1, MPI_INT, tid-1, 0, MPI_COMM_WORLD, &status);
   printf("Process %i receive %i\n", tid, message);
}

if(tid != nthreads-1)
{
   message++;
   printf("Process %i sends %i\n", tid, message);
   MPI_Send(&message, 1, MPI_INT, tid+1, 0, MPI_COMM_WORLD);
}

したがって、各プロセス(ランク0を除く)は、前のランクから値を受け取り、それを1つインクリメントしてから、次のランク(最後のランクを除く)に渡します。例えば:

  • ランク02はランク1に送信します
  • ランク1は2ランク0から受信し、それをインクリメントし3てランク2に送信します
  • ランク2は3ランク1から受け取り、それをインクリメントし4てランク3に送信します
  • ..。
  • ランクnthreads -1はランクnthreads - 22+nthreads-1から受け取ります
于 2012-12-20T13:08:44.803 に答える