Я пытаюсь реализовать Турнирный барьер, используя 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 являются блокирующими функциями. Но иногда это не так
РЕДАКТИРОВАТЬ : Вот пример выходных данных, где происходит состояние гонки. Как видно, 0 получило сообщение («1 прибыл на барьер») от 1 еще до того, как 1 отправил сообщение.
0 - победитель раунда 1
0 получено: 1 прибыл в барри
0 - победитель раунда 2
1 - проигравший в раунде 1
1 отправка достигает сообщения MSG
2 - победитель раунда 1
2 получено: 3 прибыли в барри
2 - проигравший в раунде 2
2 отправка достичь сообщения MSG
3 - проигравший в раунде 1
3 отправка достигает сообщения MSG
0 получено: 2 прибыли в барри
0 отправка сообщения пробуждения
0 отправка сообщения пробуждения
1 получено: сообщение о пробуждении от 0 с меткой в раунде 1
2 получено: сообщение о пробуждении от 0 с меткой в раунде 2
2 отправка сообщения пробуждения
3 получено: сообщение о пробуждении от 2 с меткой в раунде 1