0

我认为使用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);

但我只注意到根(接收方继续运行?)。在 Sendrecvcout之前和之后产生:

0 b4 sendrecv
2 b4 sendrecv
4 b4 sendrecv
1 b4 sendrecv
3 b4 sendrecv
5 b4 sendrecv
0 after sendrecv

在 sendrecv 之前所有进程都正常,但之后只有 root 解除阻塞。

完整来源:见第 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);
}
4

1 回答 1

1

发布的发送数量应等于发布的接收数量。在您的情况下,所有等级都发送到等级FIELD并从等级接收winner,包括FIELDwinner

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语句中。

于 2012-11-09T11:24:19.220 回答