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 からのウェイクアップ メッセージ