排序cout怪异:MPI_Send之前的MPI_Recv?

时间:2012-11-09 11:15:14

标签: c++ openmpi

我有类似的东西:

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

为什么收到之前的cout在发送之前打印?

1 个答案:

答案 0 :(得分:2)

这是两个不同的进程同时进行输出。 MPI实现通常为所有进程执行标准输出重定向,但它通常是缓冲的,以便提高性能并最小化网络利用率。然后将所有进程的输出发送到mpiexec(或发送到mpirun,或发送到用于启动MPI作业的任何其他命令)并合并到其标准输出中。来自不同进程的不同块/行最终在输出中的顺序大多是随机的,因此除非采用某种进程同步,否则不能指望来自某个等级的消息会先出现。

另请注意,MPI标准并不保证所有等级都可以写入标准输出。该标准提供MPI_IO预定义属性键,可以在MPI_COMM_WORLD上查询该属性键,以获得允许执行标准输出的进程的等级。现在大多数MPI实现都在MPI作业中的所有进程上执行输出重定向,因此返回MPI_ANY_SOURCE进行此类属性查询,但不能保证始终如此。