Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Обрамляющие функции. Начало и завершение




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

 

Инициализация библиотеки. Одна из первых инструкций в функции main (главной функции приложения):

 

MPI_Init(&argc, &argv);

 

Она получает адреса аргументов, стандартно получаемых самой main от операционной системы и хранящих параметры командной строки. В конец командной строки программы MPI-загрузчик mpirun добавляет ряд информационных параметров, которые требуются MPI_Init.

 

Аварийное закрытие библиотеки. Вызывается, если пользовательская программа завершается по причине ошибок времени выполнения, связанных с MPI:

 

MPI_Abort(описатель области связи, код ошибки MPI);

 

Вызов MPI_Abort из любой задачи принудительно завершает работу ВСЕХ задач, подсоединенных к заданной области связи. Если указан описатель MPI_COMM_WORLD, будет завершено все приложение (все его задачи) целиком, что, по-видимому, и является наиболее правильным решением. Используйте код ошибки MPI_ERR_OTHER, если не знаете, как охарактеризовать ошибку в классификации MPI.

 

Нормальное закрытие библиотеки:

 

MPI_Finalize();

 

Следует вписывать эту инструкцию перед возвращением из программы, то есть:

ü перед вызовом стандартной функции Си exit;

ü перед каждым после MPI_Init оператором return в функции main;

ü если функции main назначен тип void, и она не заканчивается оператором return, то MPI_Finalize() следует поставить в конец main.

 

Две информационных функции: сообщают размер группы (то есть общее количество задач, подсоединенных к ее области связи) и порядковый номер вызывающей задачи:

 

int size, rank;

MPI_Comm_size(MPI_COMM_WORLD, &size);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

 

Пример применения этих функций находится в файле “pi_mpi.c” – нахождение числа Пи. В нем используются, кроме уже знакомых функций, MPI_Bcast и MPI_Reduce. Эти функции рассматриваются в параграфах: MPI_Bcast – Функции коллективного обмена данными; MPI_Reduce – Функции поддержки распределенных операций).

2.4. Связь "точка-точка"

Это самый простой тип связи между задачами: одна ветвь вызывает функцию передачи данных, а другая - функцию приема. В MPI это выглядит, например, так:

 

Задача 1 передает:

 

int buf[10];

MPI_Send(buf, 5, MPI_INT, 1, 0, MPI_COMM_WORLD);

 

Задача 2 принимает:

 

int buf[10];

MPI_Status status;

MPI_Recv(buf, 10, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);

 

Аргументы функций:

 

1.Адрес буфера, из которого в задаче 1 берутся, а в задаче 2 помещаются данные. Помните, что наборы данных у каждой задачи свои, поэтому, например, используя одно и то же имя массива в нескольких задачах, Вы указываете не одну и ту же область памяти, а разные, никак друг с другом не связанные.

 

2.Размер буфера. Задается не в байтах, а в количестве ячеек. Для MPI_Send указывает, сколько ячеек требуется передать (в примере передаются 5 чисел). В MPI_Recv означает максимальную емкость приемного буфера. Если фактическая длина пришедшего сообщения меньше - последние ячейки буфера останутся нетронутыми, если больше - произойдет ошибка времени выполнения.

 

3.Тип ячейки буфера. MPI_Send и MPI_Recv оперируют массивами однотипных данных. Для описания базовых типов Си в MPI определены константы MPI_INT, MPI_CHAR, MPI_DOUBLE и так далее, имеющие тип MPI_Datatype. Их названия образуются префиксом "MPI_" и именем соответствующего типа (int, char, double,...), записанным заглавными буквами. Пользователь может "регистрировать" в MPI свои собственные типы данных, например, структуры, после чего MPI сможет обрабатывать их наравне с базовыми.

 

4.Номер задачи, с которой происходит обмен данными. Все задачи внутри созданной MPI группы автоматически нумеруются от 0 до (размер группы-1). В примере задача 0 передает задаче 1, задача 1 принимает от задачи 0.

 

5.Идентификатор сообщения. Это целое число от 0 до 32767, которое пользователь выбирает сам. Оно служит той же цели, что и, например, расширение файла - задача-приемник:

ü по идентификатору определяет смысл принятой информации;

ü сообщения, пришедшие в неизвестном порядке, может извлекать из общего входного потока в нужном алгоритму порядке. Хорошим тоном является обозначение идентификаторов символьными именами посредством операторов "#define" или "const int".

 

6.Описатель области связи (коммуникатор). Должен быть одинаковым для MPI_Send и MPI_Recv.

 

7.Статус завершения приема. Содержит информацию о принятом сообщении: его идентификатор, номер задачи-передатчика, код завершения и количество фактически пришедших данных.

2.5. Прием и передача: MPI_Sendrecv

Некоторые конструкции с приемо-передачей применяются очень часто. Пример – обмен данными с соседями по группе (для четного количества ветвей в группе):

 

MPI_Comm_size(MPI_COMM_WORLD, &size);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if(rank % 2) {

/* Ветви с четными номерами сначала

* передают следующим нечетным ветвям,

* потом принимают от предыдущих

*/

MPI_Send(..., (rank+1) % size,...);

MPI_Recv(..., (rank+size-1) % size,...);

} else {

/* Нечетные ветви поступают наоборот:

* сначала принимают от предыдущих ветвей,

* потом передают следующим.

*/

MPI_Recv(..., (rank-1) % size,...);

MPI_Send(..., (rank+1) % size,...);

}

 

Другой пример – посылка данных и получение подтверждения:

 

MPI_Send(..., anyRank,...); /* Посылаем данные */

MPI_Recv(..., anyRank,...); /* Принимаем подтверждение */

 

Ситуация настолько распространенная, что в MPI специально введены две функции, осуществляющие одновременно посылку одних данных и прием других. Первая из них - MPI_Sendrecv. Она имеет 12 параметров: первые 5 параметров такие же, как у MPI_Send, остальные 7 параметров такие же, как у MPI_Recv. Один ее вызов проделывает те же действия, для которых в первом фрагменте требуется блок IF-ELSE с четырьмя вызовами. Следует учесть, что:

ü и прием, и передача используют один и тот же коммуникатор;

ü порядок приема и передачи данных MPI_Sendrecv выбирает автоматически; гарантируется, что автоматический выбор не приведет к "клинчу";

ü MPI_Sendrecv совместима с MPI_Send и MPI_Recv, т.е может "общаться" с ними.

 

MPI_Sendrecv_replace помимо общего коммуникатора использует еще и общий для приема-передачи буфер. Не очень удобно, что параметр count получает двойное толкование: это и количество отправляемых данных, и предельная емкость входного буфера. Показания к применению:

ü принимаемые данные должны быть заведомо НЕ ДЛИННЕЕ отправляемых;

ü принимаемые и отправляемые данные должны иметь одинаковый тип;

ü отправляемые данные затираются принимаемыми.

 

MPI_Sendrecv_replace так же гарантированно не вызывает клинча.

Клинч (deadlock, тупик) – процесс находится в состоянии тупика, если ожидает события, которое никогда не произойдет. Пример клинча:

 

-- Ветвь 1 -- -- Ветвь 2 --

Recv(из ветви 2) Recv(из ветви 1)

Send(в ветвь 2) Send(в ветвь 1)

 

Это вызовет клинч: функция приема не вернет управления до тех пор, пока не получит данные; поэтому функция передачи не может приступить к отправке данных; поэтому функция приема... и так до самого SIG_KILL.

Коллективные функции

Под термином "коллективные" в MPI подразумеваются три группы функций:

ü функции коллективного обмена данными;

ü точки синхронизации, или барьеры;

ü функции поддержки распределенных операций.

 

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

Для ограничения области действия коллективной функции частью ветвей, создается временная группа/область связи/коммуникатор на базе существующих, как это показано в разделе про коммуникаторы.





Поделиться с друзьями:


Дата добавления: 2016-07-29; Мы поможем в написании ваших работ!; просмотров: 476 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Свобода ничего не стоит, если она не включает в себя свободу ошибаться. © Махатма Ганди
==> читать все изречения...

2370 - | 2121 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.011 с.