Когда мне нужно использовать MPI_Barrier()?

Интересно, когда мне нужно использовать барьер? Нужно ли мне это, например, до/после разброса/сбора? Или OMPI должен убедиться, что все процессы достигли этой точки, прежде чем разбрасывать/собирать? Аналогично, могу ли я ожидать, что после широковещательной рассылки все процессы уже получат сообщение?


person Jiew Meng    schedule 09.11.2012    source источник


Ответы (3)


Все коллективные операции в MPI до MPI-3.0 являются блокирующими, а это означает, что безопасно использовать все переданные им буферы после их возврата. В частности, это означает, что все данные были получены при возврате одной из этих функций. (Однако это не означает, что все данные были отправлены!) Таким образом, MPI_Barrier не нужен (или очень полезен) до/после коллективных операций, если все буферы уже действительны.

Также обратите внимание, что MPI_Barrier не ожидает волшебным образом неблокирующих вызовов. Если вы используете неблокирующую отправку/получение и оба процесса ожидают на MPI_Barrier после пары send/recv, не гарантируется, что процессы отправили/получили все данные после MPI_Barrier. Вместо этого используйте MPI_Wait (и его друзей). Итак, следующий фрагмент кода содержит ошибки:

/* ERRORNOUS CODE */

Code for Process 0:
Process 0 sends something using MPI_Isend
MPI_Barrier(MPI_COMM_WORLD);
Process 0 uses buffer passed to MPI_Isend // (!)

Code for Process 1:
Process 1 recvs something using MPI_Irecv
MPI_Barrier(MPI_COMM_WORLD);
Process 1 uses buffer passed to MPI_Irecv // (!)

Обе линии, отмеченные (!), небезопасны!

MPI_Barrier полезен только в нескольких случаях. Большую часть времени вам все равно, синхронизируются ли ваши процессы. Лучше почитайте про блокировку и неблокировку звонков!

person Markus Mayr    schedule 09.11.2012
comment
Почему 1-й (!) является ошибкой? Процесс 0 по-прежнему будет иметь свой собственный буфер? Кроме того, поскольку это отправка, принимающая сторона не изменит его, верно? - person Jiew Meng; 09.11.2012
comment
@JiewMeng MPI не должен читать из буфера сразу после вызова MPI_Isend. Если вы измените его в (!), вы можете отправить что-то другое. Я не совсем уверен в этом, но думаю, что поведение в данном случае не определено. - person Markus Mayr; 09.11.2012
comment
Я немного обновил ваш ответ, так как MPI-3.0 представил неблокирующие коллективы. - person Hristo Iliev; 09.11.2012
comment
В частности, это означает, что все данные были получены при возврате одной из этих функций. (Однако это не означает, что все данные были отправлены!) - разве это не противоречит? Как все данные могут быть получены без отправки? Возможно, вы имели в виду, что, поскольку все коллективные операции блокируются, безопасно повторно использовать буфер с данными для отправки после вызова send (потому что именно в этом заключается блокировка), потому что он копируется MPI (не обязательно в том же как для буферизованной отправки MPI_Bsend)? Конечно, правильно, что при блокировке возврата отправки мы не можем быть уверены, что данные были получены. - person falconepl; 13.03.2015
comment
И чтобы было понятно... хотя при блокировке отправки мы не можем быть уверены, что данные были получены, если мы использовали синхронизированную блокировку отправки, то, когда отправка возвращается, мы уверены, что получатель получил наше сообщение. - person falconepl; 13.03.2015
comment
@falconepl Ты прав, это то, что я говорю. На мой взгляд, формулировка непротиворечива, но я надеюсь, что ваши комментарии прояснят ситуацию для людей, которые думают так же, как и вы. Спасибо! Просто повторю это еще раз: блокирующая отправка не означает, что сообщение было отправлено и получено, просто вы можете повторно использовать буферы. Блокирующий вызов приема подразумевает, что все данные были получены. - person Markus Mayr; 02.06.2015
comment
@MarkusMayr ​​Привет, MarkusMayr, Ваше высказывание все еще сбивает меня с толку после того, как я прочитал его несколько раз ... Что означает Однако это не означает, что все данные были отправлены! иметь в виду?? Не могли бы вы объяснить это более ясно? - person user15964; 25.03.2016
comment
@ user15964: Ваша реализация MPI может создать копию буферов, которые вы передали блокирующему вызову. Он может использовать эту копию для отправки данных в более поздний момент времени. Для коллективной операции возможно, что ваш процесс еще не завершил отправку данных другим процессам, но уже получил все данные, которые ему нужны, когда возвращается блокирующий вызов. - person Markus Mayr; 25.03.2016
comment
@MarkusMayr ​​Это намного яснее, я думаю, что теперь понимаю вашу точку зрения. Большое спасибо! - person user15964; 26.03.2016
comment
Спасибо за ответ. Не могли бы вы пролить свет на то, нужен ли MPI_Barrier после вызова функций топологии, таких как MPI_Cart_Create (и перед дальнейшей обработкой с помощью MPI_Cart_Shift или, например, с MPI_Scatterv/Gatherv)? - person Śubham; 03.12.2019

Одним из вариантов использования MPI_Barrier является, например, управление доступом к внешнему ресурсу, такому как файловая система, доступ к которому не осуществляется с помощью MPI. Например, если вы хотите, чтобы каждый процесс последовательно записывал информацию в файл, вы можете сделать это следующим образом:

int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
for ( int ii = 0; ii < size; ++ii ) {
    if ( rank == ii ) {
        // my turn to write to the file
        writeStuffToTheFile();
    }
    MPI_Barrier(MPI_COMM_WORLD);
}

Таким образом, вы можете быть уверены, что никакие два процесса не вызывают одновременно writeStuffToTheFile.

person Edric    schedule 09.11.2012

Может MPI_Barrier() используется не часто, но полезно. На самом деле, даже если вы использовали синхронную связь, MPI_Send/Recv() может только обеспечить синхронизацию двух процессов. В моем проекте cuda+MPI я использовал только асинхронную связь. Я обнаружил, что в некоторых случаях, если я не использую MPI_Barrier(), за которой следует функция Wait(), очень вероятно, что два процесса (gpu) хотят передавать данные друг другу одновременно, что может привести к серьезным последствиям. снизить эффективность программы. Вышеупомянутая ошибка всегда приводила меня в бешенство, и мне потребовалось несколько дней, чтобы найти ее. Поэтому вы можете тщательно подумать, использовать ли MPI_Barrier(), когда вы используете MPI_Isend/Irecv в своей программе. Иногда синхронизация процессов не только необходима, но и ОБЯЗАТЕЛЬНА, особенно ваша программа работает с устройством.

person Freezenfire    schedule 29.09.2015