Вычислительный центр им. А.А. Дородницына РАН    

Раздел виртуального курса
Параллельное программирование в интерфейсе MPI


Вопросы по MPI коллективному обмену сообщениями I

  1. Утверждение, что функция коллективной коммуникации является локально блокирующей, означает, что следующее предложение в программе на отдельном узле не исполнится пока

    A. все процессы в данном задании не завершили это предложение
    B. все процессы названного коммуникатора не завершили это предложение
    C. локальный процесс не завершил это предложение
    D. корневой процесс не завершил это предложение.

  2. Корневой процесс в вызове MPI_Bcast, как это реальзовано MPICH, исполняет следующее его предложение после того как:

    A. все процессы в данном задании подтвердили получение данных;
    B. все процессы названного коммуникатора подтвердили получение данных
    C. все процессы названного коммуникатора достигли этого вызова
    D. все данные поставлены в очередь на отправку, даже если некоторые процессы могли еще не достичь этого вызова.

  3. Отметьте все, что подходит: какой из следующих фрагментов SPMD-кода на С ошибочен? Предполагаем, что коды запускаются не менее чем на 2-х процессорах, и что все строки кода, относящиеся к вопросу, показаны.

    ierror = MPI_Comm_rank(MPI_COMM_WORLD, rank)
    if (rank == 0) {
    ierror = MPI_Bcast(buf, 1, MPI_INTEGER, 0, MPI_COMM_WORLD)
    } else {
    // нет вызова MPI_Bcast
    }

    rbuf = 1000;

    do while (rbuf .gt. 1)
    // расчет sbuf не показан
    ierror = MPI_Reduce (sbuf, rbuf, 1, MPI_REAL, MPI_MAX, root, MPI_COMM_WORLD);
    end do

    ierror = MPI_Reduce(buf, buf, 1, MPI_INTEGER, MPI_SUM, 0, MPI_COMM_WORLD);

    ierror = MPI_Scatter(sbuf, 5, MPI_REAL, rbuf, 10, MPI_REAL, 0, MPI_COMM_WORLD);

    ierror = MPI_Comm_size (MPI_COMM_WORLD, size);
    ierror = MPI_Gather(sbuf, 5, MPI_REAL, rbuf, 5*size, MPI_REAL, 0, MPI_COMM_WORLD);

  4. Отметьте все, что подходит. Что безопасно полагать, после того как вызов MPI_ALLGATHER возвращает управление?

    Отправляющий буфер может быть безопасно переписан.
    Получающий буфер может быть благополучно использован.
    Все участвующие процессы возвратили управление из вызова.

  5. Что в вызове MPI_Scatter не_всегда_верно?

    A. каждый процесс должен получить так много элементов, сколько отправил корневой процесс
    B. каждый процесс должен получить так много байтов, сколько отправил корневой процесс
    C. каждый процесс в названном коммуникаторе должен вызвать MPI_Scatter, определяя тот же самый корневой процесс;
    D. каждый процесс должен определить получающийся буфер, размер которого равен, по крайней мере, 1/N всех данных, отправленных корневым процессом.

  6. При вызове MPI_Gather что когда-либо_не_верно?

    A. получающийся буфер на корневом узле имеет размер более чем в N раз больше размера буферов на других узлах
    B. буфер на корневом узле равен размеру буферов на узлах отправки
    C. один из некорневых процессов переходит к его следующему предложению прежде, чем это делает корневой процесс
    D. корневой процесс переходит к следующему предложению прежде, чем один из некорневых процессов достигает его вызова MPI_Gather.

  7. Что из следующего недопустимо? Один и тот же процесс в коммуникаторе вызывает MPI_Gather с различным

    A. буфером получателя
    B. буфером отправителя
    C. числом и типом данных, но произведение числа и размера типа данных то же самое, как у других
    D. корневым рангом

  8. Что недопустимо для вызова MPI_Reduce, но приемлемо для MPI_Gather? Один процесс определяет различный

    A. буфер получателя
    B. буфер отправителя
    C. тип данных и число, но произведение числа и размера типа данных то же самое, как у других
    D. корневой ранг

  9. В "Основах MPI программирования" введено понятие коммуникатора и обсужден вопрос, каким образом различные процессы могли иметь различные разряды в различных коммуникаторах. Следующие процессы имеют следующие разряды в двух коммуникаторах:

    Ранг в коммуникаторе
    процесс 1 процесс 2 процесс 3 процесс 4
    comm1 0 1 2 3
    comm2 3 2 1 0

    После следующего фрагмента SPMD-кода на С :

    MPI_Comm_rank (comm1, &rank1);
    MPI_Gather(&rank1, 1, MPI_INT, &rbuf, 1, MPI_INT, 0, comm1);

    - рассмотрим вопрос: Что содержит массив rbuf на корневом процессе?

    {0,1,2,3}
    {3,2,1,0}

  10. Для коммуникаторов описанных в вопросе 9, что содержит rbuf на корневом процессе после фрагмента этого SPMD C-кода?

    MPI_Comm_rank (comm2, &rank2);
    MPI_Gather(&rank2, 1, MPI_INT, &rbuf, 1, MPI_INT, 0, comm2);

    {0,1,2,3}
    {3,2,1,0}

  11. Может ли тот же самый процесс быть корневым для вызовов MPI_Gather в вопросах 9 и 10?

    да
    нет

  12. Некий пользователь вызывает MPI_Reduce с оператором MPI_BOR. Входной вектор на каждой из четырех задач имеет целые числа от 1 до 4 по-порядку. Выходным вектором будут

    A. целые от 1 до 4 по-порядку
    B. целые от 1 до 4 в обратном порядке
    C. все 0'ые
    D. все 7'ки

  13. Некий пользователь снова вызывает MPI_Reduce с оператором MPI_BOR. В это время входной вектор на каждой из четырех задач имеет целые числа от 1 до 4, но они смещены покругу, так что список начинается с 1 на задаче 0, 2 на задаче 1, и т.д. Выходным вектором будут

    A. целые от 1 до 4 по-порядку
    B. целые от 1 до 4 в обратном порядке
    C. все 0'ые
    D. все 7'ки

  14. Как много стадий будет в наиболее эффективной реализации функции MPI_Allreduce?

    A. 1
    B. log2(N)
    C. 2*log2(N)
    D. N

  15. Код был организован так, чтобы он имел хороший баланс загрузки, но процессы подвержены частым прерываниям, которые заставляют их временно выходить из синхронизации существенными количествами. Если задаче 0 требуется широко распределить большое количество данных (> острого порога) от буфера посреди итерации, то какая стратегия подвергнется наименьшей синхронизационной накладке?

    A. MPI_Bcast
    B. MPI_Send в цикле на задаче 0
    C. MPI_Isend в цикле на задаче 0 сопровожденным вызовом MPI_Waitall прямо сразу после цикла
    D. все они примерно одинаковы.





ФИО: