Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

Также обратите внимание, что MPI_Barrier не волнует ожидание неблокирующих вызовов. Если вы используете неблокирующий send/recv, и оба процесса ожидают 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 полезен только в нескольких случаях. В большинстве случаев вам не важно, синхронизируются ли ваши процессы. Лучше читайте о блокирующих и неблокирующих вызовах!

Ответ 2

Одним из способов использования 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.

Ответ 3

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