我认为使用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);
}
答案 0 :(得分:1)
发布的发送数量应该等于发布的发送数量。在您的情况下,所有排名都会发送到排名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
的{{1}}次呼叫将无法完成其发送。 MPI_Sendrecv
也是如此。它应该发送winner
消息,但由于它只执行numprocs
一次,因此只发送一条消息,因此MPI_Sendrecv
对numprocs-1
的调用将无法完成其接收。< / p>
还有另一个错误。 MPI标准要求发送和接收缓冲区不相交(即它们不应重叠),这与您的代码不同。您的发送和接收缓冲区不仅重叠,而且它们是同一个缓冲区。如果要在同一缓冲区中执行交换,MPI将提供MPI_Sendrecv
操作。
我不确定您要使用此MPI_Sendrecv_replace
语句尝试实现的目标,但我强烈怀疑您需要将其置于MPI_Sendrecv
语句中。