У меня есть что-то вроде:
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
после получения отпечатков до того, как перед отправкой?
Это два разных процесса, выполняющих вывод одновременно. Реализации MPI обычно выполняют стандартное перенаправление вывода для всех процессов, но оно обычно буферизуется для повышения производительности и минимизации использования сети. Выходные данные всех процессов затем отправляются mpiexec
(или для mpirun
или любой другой команде, используемой для запуска задания MPI) и объединенной в стандартный вывод. Порядок, в котором разные чанки / строки из разных процессов оказываются на выходе, в основном случайный, поэтому вы не должны ожидать, что сообщение с определенным рангом появится первым, если не используется какой-либо процесс синхронизации.
Также обратите внимание, что стандарт MPI не гарантирует, что для всех рангов возможна запись в стандартный вывод. Стандарт предусматривает MPI_IO
предопределенный ключ атрибута, по которому можно запросить MPI_COMM_WORLD
чтобы получить ранг процесса, которому разрешено выполнять стандартный вывод. В настоящее время большинство реализаций MPI выполняют перенаправление вывода для всех процессов в задании MPI и, таким образом, возвращают MPI_ANY_SOURCE
для таких запросов атрибутов, но это не всегда так.
Других решений пока нет …