Огромная разница в MPI_Wtime () после использования MPI_Barrier ()?

Это часть кода.

    if(rank==0) {
temp=10000;
var=new char[temp] ;
MPI_Send(&temp,1,MPI_INT,1,tag,MPI_COMM_WORLD);
MPI_Send(var,temp,MPI_BYTE,1,tag,MPI_COMM_WORLD);
//MPI_Wait(&req[0],&sta[1]);
}
if(rank==1) {
MPI_Irecv(&temp,1,MPI_INT,0,tag,MPI_COMM_WORLD,&req[0]);
MPI_Wait(&req[0],&sta[0]);
var=new char[temp] ;
MPI_Irecv(var,temp,MPI_BYTE,0,tag,MPI_COMM_WORLD,&req[1]);
MPI_Wait(&req[0],&sta[0]);
}
//I am talking about this MPI_BarrierMPI_Barrier(MPI_COMM_WORLD);
cout << MPI_Wtime()-t1 << endl ;
cout << "hello " << rank  << " " << temp << endl ;
MPI_Finalize();
}

1. при использовании MPI_Barrier — Как и ожидалось, весь процесс занимает почти одинаковое количество времени, порядка 0,02.

2. когда не используется MPI_Barrier () — корневой процесс (отправка сообщения) ждет дополнительного времени.
и (MPI_Wtime -t1) сильно варьируется, а время, затрачиваемое корневым процессом, составляет порядка 2 секунд.

Если я не ошибаюсь, MPI_Barrier используется только для приведения всех запущенных процессов на одном уровне. так почему же время, когда я использую MPI_Barrier (), не составляет 2 секунды (минимум всех процессов, т. е. корневой процесс). Пожалуйста, объясни ?

1

Решение

Спасибо Уэсли Блэнду за то, что он заметил, что вы ждете дважды по одному и тому же запросу. Вот объяснение того, что на самом деле происходит.

Есть что-то под названием прогрессия асинхронных (неблокирующих) операций в MPI. Именно тогда происходит фактическая передача. Прогрессирование может происходить разными способами и в разных точках библиотеки MPI. Когда вы публикуете асинхронную операцию, ее выполнение может быть отложено на неопределенное время, даже до точки, которую вы вызываете MPI_Wait, MPI_Test или некоторый вызов, который привел бы к тому, что новые сообщения были отправлены или извлечены из очереди приема / передачи. Вот почему очень важно позвонить MPI_Wait или же MPI_Test как можно быстрее после начала неблокирующей операции.

Открытый MPI поддерживает поток фоновой прогрессии, который заботится о продвижении операций, даже если условие в предыдущем абзаце не выполняется, например, если MPI_Wait или же MPI_Test никогда не вызывается в дескрипторе запроса. Это должно быть явно включено при сборке библиотеки. Он не включен по умолчанию, так как фоновая прогрессия увеличивает задержку операций.

Что происходит в вашем случае, так это то, что вы ожидаете неверный запрос при втором звонке MPI_Wait в приемнике, следовательно, прогрессия второго MPI_Irecv операция откладывается. Размер сообщения превышает 40 КиБ (10000 × 4 байта + издержки конверта), что превышает предельное значение по умолчанию в Open MPI (32 КиБ). Такие сообщения отправляются с использованием протокола рандеву, который требует отправки и выполнения операций отправки и получения. Операция приема не продвигается и, следовательно, операция отправки в блоках ранга 0 до тех пор, пока в какой-то момент времени процедуры очистки, которые MPI_Finalize в ранге 1 звонки в конечном счете прогрессируют получение

Когда вы положите вызов MPI_Barrierэто приводит к прогрессированию выдающегося приема, действующего почти как неявный призыв к MPI_Wait, Вот почему отправка в ранге 0 завершается быстро, и оба процесса идут вовремя.

Обратите внимание, что MPI_Irecvсразу после MPI_Wait эквивалентно простому звонку MPI_Recv, Последнее не только проще, но и менее подвержено простым опечаткам, подобным тому, который вы сделали.

3

Другие решения

Ты ждешь по одному и тому же запросу два раза для твоего Irecv. второй — тот, который занимал бы все время, и с тех пор, как его пропустили, ранг 0 становится намного впереди.

MPI_BARRIER может быть реализован так, что некоторые процессы могут выходить из алгоритма раньше остальных, если процессы входят в него. Это, наверное, то, что здесь происходит.

0

В тестах, которые я провел, я не вижу почти никакой разницы во времени выполнения. Основное отличие состоит в том, что вы, кажется, выполняете свой код один раз, тогда как я повторял ваш код тысячи раз, а затем взял среднее значение. Мой вывод ниже:

With the barrier
[0]: 1.65071e-05
[1]: 1.66872e-05
Without the barrier
[0]: 1.35653e-05
[1]: 1.30711e-05

Поэтому я бы предположил, что любые изменения, которые вы видите, являются результатом вашей операционной системы, а не вашей программы.

Кроме того, почему вы используете MPI_Irecv в сочетании с MPI_wait, а не просто MPI_recv?

0
По вопросам рекламы [email protected]