2

MPI を使用してトーナメント バリアを実装しようとしています。ここに、私が書いたコードがあります。到着フェーズと起床フェーズのみ書いています

//Arrival phase
while(1)
{
    if((!strcmp(round[my_id][round_num].role,"winner"))||(!strcmp(round[my_id][round_num].role,"champion")))
    {
       printf("%d is the winner of round %d\n",my_id,round_num);
       MPI_Recv(&reach_msg, sizeof(reach_msg), MPI_BYTE, round[my_id][round_num].opponent, tag, MPI_COMM_WORLD, &status);
       printf("%d received: %s\n",my_id,reach_msg);
    }

    else if(!strcmp(round[my_id][round_num].role,"loser"))
    {
       printf("%d is the loser of round %d\n",my_id,round_num);
       sprintf(reach_msg,"%d arrived at the barrier",my_id);
       MPI_Send(reach_msg,strlen(reach_msg+1),MPI_BYTE,round[my_id][round_num].opponent,tag,MPI_COMM_WORLD);
       MPI_Recv(wakeup_msg,sizeof(wakeup_msg),MPI_BYTE,round[my_id][round_num].opponent,tag,MPI_COMM_WORLD,&status);
       printf("%d received: %s\n",my_id,wakeup_msg);
    }

if(round_num==num_rounds)
       break;
    else
       round_num++;
}

printf("%d is out of arrival tree\n",my_id);

//wakeup tree
      while(1)
     {
       printf("%d prints: round num is: %d\n",my_id,round_num);
       if(round_num==0)
            break;
       sprintf(wakeup_msg,"wakeup msg from %d of %d",my_id,P);

       if((!strcmp(round[my_id][round_num].role,"winner"))||(!strcmp(round[my_id][round_num].role,"champion")))
       MPI_Send(wakeup_msg,strlen(wakeup_msg+1),MPI_BYTE,round[my_id][round_num].opponent,tag,MPI_COMM_WORLD);
       round_num--;
      }

    MPI_Finalize();
    return 0;
   }

競合状態が発生する理由がわかりません。MPI_Send と MPI_Recv はブロック機能だと思います。しかし、時々、そのように動作しないことがあります

編集: これは、競合状態が発生するサンプル出力です。ご覧のとおり、1 がメッセージを送信する前であっても、0 は 1 からメッセージ ("1 がバリアに到着しました") を受信しました。

0 がラウンド 1 の勝者

0 受信: 1 がバリーに到着

0 はラウンド 2 の勝者です

1はラウンド1の敗者です

1送信リーチメッセージ

2人がラウンド1の勝者

2 受信: 3 がバリーに到着

2 ラウンド 2 の敗者

2 到達メッセージの送信

3 がラウンド 1 の敗者

3 到達メッセージの送信

0 受信: 2 がバリーに到着

0 ウェイクアップ メッセージを送信中

0 ウェイクアップ メッセージを送信中

1 受信: ラウンド 1 でタグ付きの 0 からのウェイクアップ メッセージ

2 受信: ラウンド 2 でタグ付きの 0 からのウェイクアップ メッセージ

2 ウェイクアップ メッセージの送信

3 受信: ラウンド 1 でタグ付きの 2 からのウェイクアップ メッセージ

4

3 に答える 3

2

私の経験では、基盤となるアルゴリズムではなく、観察に問題がある可能性が最も高いです。通常、printfこのような設定の は単に順不同で到着します。あなたはしなければならないでしょう

  • 出力にタイムスタンプを入れる
  • 各 MPI プロセスごとに 1 つずつ、異なるファイルに書き込みます
  • タイムスタンプに従って並べ替えて、それらをマージして戻します
于 2011-10-21T06:50:57.217 に答える
1

mpi プログラムをデバッグする場合、print ステートメントは一般的にあまり良い解決策ではありません。印刷ステートメントは、ネットワークを介してさまざまなノードからコンソールに送信する必要があり、前にキャッシュされます。

それをデバッグするには、各プロセッサが独自の出力ファイルに書き込めるようにする必要があります。または、std::cerr を使用してキャッシュを無効にするか、何らかの方法で printf のキャッシュを無効にする、1 つのプロセッサのみにステートメントを出力させます。

于 2011-10-22T00:21:12.087 に答える
0

私はあなたの問題を完全に理解しているかどうかわかりません...あなたの質問にコードの出力を追加することは役立つかもしれません。

私が確かに言えることは、MPI_SendとMPI_Recvが確実に関数をブロックしているということです。代わりに非ブロッキング関数(つまり、MPI_IsendとMPI_Irecv)を使用しようとしましたか?はいの場合、それはあなたの問題を解決しましたか?

于 2011-10-21T06:15:03.387 に答える