我认为使用MPI_Sendrecv
MPI_Sendrecv(&ballPos, 2, MPI_INT, FIELD, NEW_BALL_POS_TAG, &ballPos, 2, MPI_INT, winner, NEW_BALL_POS_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
但是我只注意到根(接收方是否继续运行?)。在Sendrecv之前和之后产生
cout
会产生:0 b4 sendrecv
2 b4 sendrecv
4 b4 sendrecv
1 b4 sendrecv
3 b4 sendrecv
5 b4 sendrecv
0 after sendrecv
所有进程在sendrecv之前都可以,但是之后只有root才能取消阻止。
Full source:参见第147行
更新
结果应该类似于以下内容
if (rank == winner) {
ballPos[0] = rand() % 128;
ballPos[1] = rand() % 64;
cout << "new ball pos: " << ballPos[0] << " " << ballPos[1] << endl;
MPI_Send(&ballPos, 2, MPI_INT, FIELD, NEW_BALL_POS_TAG, MPI_COMM_WORLD);
} else if (rank == FIELD) {
MPI_Recv(&ballPos, 2, MPI_INT, winner, NEW_BALL_POS_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
最佳答案
发送的发送数量应等于发送的接收数量。在您的情况下,所有等级都发送到等级FIELD
并从等级winner
接收,包括FIELD
和winner
:
Rank Sends to Receives from
----------------------------------
0 (FIELD) FIELD winner
1 FIELD winner
2 FIELD winner
... ... ...
winner FIELD winner
... ... ...
numprocs-1 FIELD winner
(此类表有时可能非常有用)
因此,
FIELD
应该接收numprocs
消息,但是它只执行一次MPI_Sendrecv
,因此对numprocs-1
的MPI_Sendrecv
调用将无法完成其发送。 winner
也是如此。它应该发送numprocs
消息,但由于它仅执行一次MPI_Sendrecv
,因此仅发送一条消息,因此对numprocs-1
的MPI_Sendrecv
调用将无法完成其接收。还有另一个错误。 MPI标准要求发送缓冲区和接收缓冲区不相交(即它们不应重叠),而您的代码则不是这种情况。您的发送和接收缓冲区不仅重叠,而且是一个缓冲区,并且是同一缓冲区。如果要在同一缓冲区中执行交换,则MPI提供
MPI_Sendrecv_replace
操作。我不确定您要使用此
MPI_Sendrecv
语句实现什么目的,但是我强烈怀疑您需要将其放入if
语句中。