订购COUT怪异的订购:MPI_RECV MPI_SEND之前

Ordering of cout weird: MPI_Recv before MPI_Send?

本文关键字:MPI RECV SEND 之前 COUT 订购      更新时间:2023-10-16

我有类似的东西:

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);
    cout << "2 new ball pos: " << ballPos[0] << " " << ballPos[1] << endl;
}

,但我在控制台中看到:

new ball pos: 28 59
2 new ball pos: 28 59

为什么ISIT在发送前接收打印后的cout

这是同时进行输出的两个不同过程。MPI实现通常为所有过程执行标准输出重定向,但是通常会进行缓冲,以提高性能并最大程度地减少网络利用率。然后将所有进程的输出发送到mpiexec(或mpirun或用于启动MPI作业的其他命令),并将其合并到其标准输出中。来自不同过程的不同块/行结束的顺序大多是随机的,因此,除非采用某种类型的同步synchronisatoin,否则您一定不要期望某个等级的消息会首先出现。

还要注意,MPI标准不能保证所有等级都可以写入标准输出。该标准提供了MPI_IO预定属性密钥,可以在MPI_COMM_WORLD上查询,以获取允许执行标准输出的过程的等级。如今,大多数MPI实现都在MPI作业中的所有进程上执行输出重定向,因此对于此类属性查询返回MPI_ANY_SOURCE,但这不能始终是这种情况。