我正在嘗試使用MPI實現錦標賽屏障。這裏是我寫的代碼。我只寫了到達階段和喚醒階段與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發送喚醒信息msg
0發送喚醒味精
1接收:喚醒MSG從0附有標籤在第1輪
2接收:喚醒MSG從0附有標籤在第2輪
2發送喚醒味精
3收到:來自2的喚醒信息,第2輪帶有標籤
通過競爭條件,我的意思是接收過程即使在發送過程發送之前也會收到消息! – CuriousCoder
你的程序違反因果關係是不太可能的。你只是以這種方式看到*打印*。 IIRC MPI(儘管它可能取決於實現)是否在進程0上打印所有內容,這意味着進程1上的「printf」實際上將其數據發送給進程0打印。 – user786653
@ user786653:我實際上正在運行此代碼同一臺機器。我被分配了一組機器。如果我在集羣的不同機器上分發代碼並運行該程序,該怎麼辦? printf語句是否仍然會被髮送到進程0進行打印? – CuriousCoder