Студопедия — Блокирующие коммуникационные операции
Студопедия Главная Случайная страница Обратная связь

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

Блокирующие коммуникационные операции






Синтаксис базовых коммуникационных функций MPI_Send и MPI_Recv был рассмотрен в разделе 2, поэтому здесь мы рассмотрим только семантику этих операций.

В стандартном режиме выполнение операции обмена включает три этапа:

1. Передающая сторона формирует пакет сообщения, в который помимо передаваемой информации упаковываются адрес отправителя (source), адрес получателя (dest), идентификатор сообщения (tag) и коммуникатор (comm). Этот пакет передается отправителем в буфер, и на этом функция посылки сообщения заканчивается.

2. Сообщение системными средствами передается адресату.

3. Принимающий процессор извлекает сообщение из системного буфера, когда у него появится потребность в этих данных. Содержательная часть сообщения помещается в адресное пространство принимающего процесса (параметр buf), а служебная в параметр status.

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

  • коммуникатора (comm), поскольку каждый процесс может одновременно входить в несколько областей связи;
  • номера отправителя в этой области связи (source);
  • идентификатора сообщения (tag), который используется для взаимной привязки конкретной пары операций посылки и приема сообщений.

Параметр count (количество принимаемых элементов сообщения) в процедуре приема сообщения должен быть не меньше, чем длина принимаемого сообщения. При этом реально будет приниматься столько элементов, сколько находится в буфере. Такая реализация операции чтения связана с тем, что MPI допускает использование расширенных запросов для идентификаторов сообщений (MPI_ANY_TAG - читать сообщение с любым идентификатором) и для адресов отправителя (MPI_ANY_SOURCE - читать сообщение от любого отправителя). Не допускается расширенных запросов для коммуникаторов. Расширенные запросы возможны только в операциях чтения. Интересно отметить, что таким же образом организованы операции обмена в PSE nCUBE2 [1]. В этом отражается фундаментальное свойство механизма передачи сообщений - асимметрия операций передачи и приема сообщений, связанная с тем, что инициатива в организации обмена принадлежит передающей стороне.

Таким образом, после чтения сообщения некоторые параметры могут оказаться неизвестными, а именно: число считанных элементов, идентификатор сообщения и адрес отправителя. Эту информацию можно получить с помощью параметра status. Переменные status должны быть явно объявлены в MPI программе. В языке C status - это структура типа MPI_Status с тремя полями MPI_SOURCE, MPI_TAG, MPI_ERROR. В языке FORTRAN status - массив типа INTEGER размера MPI_STATUS_SIZE. Константы MPI_SOURCE, MPI_TAG и MPI_ERROR определяют индексы элементов. Назначение полей переменной status представлено в таблице 4.

Таблица 4. Назначение полей переменной status

Поля status C FORTRAN
Процесс-отправитель status.MPI_SOURCE status(MPI_SOURCE)
Идентификатора сообщения status.MPI_TAG status(MPI_TAG)
Код ошибки status.MPI_ERROR status(MPI_ERROR)

 

Как видно из таблицы 4, количество считанных элементов в переменную status не заносится. Для определения числа фактически полученных элементов сообщения необходимо использовать специальную функцию MPI_Get_count:

C:

int MPI_Get_count (MPI_Status *status, MPI_Datatype datatype, int *count)

FORTRAN:

MPI_GET_COUNT (STATUS, DATATYPE, COUNT, IERROR)

INTEGER STATUS (MPI_STATUS_SIZE), DATATYPE, COUNT, IERROR

IN status - атрибуты принятого сообщения;
IN datatype - тип элементов принятого сообщения;
OUT count - число полученных элементов.

Подпрограмма MPI_Get_count может быть вызвана либо после чтения сообщения (функциями MPI_Recv, MPI_Irecv), либо после опроса факта поступления сообщения (функциями MPI_Probe, MPI_Iprobe). Операция чтения безвозвратно уничтожает информацию в буфере приема. При этом попытка считать сообщение с параметром count меньше, чем число элементов в буфере, приводит к потере сообщения. Определить параметры полученного сообщения без его чтения можно с помощью функции MPI_Probe.

C:

int MPI_Probe (int source, int tag, MPI_Comm comm, MPI_Status *status)

FORTRAN:

MPI_PROBE (SOURCE, TAG, COMM, STATUS, IERROR)

INTEGER SOURCE, TAG, COMM, STATUS(MPI_STATUS_SIZE), IERROR

IN source - номер процесса-отправителя;
IN tag - идентификатор сообщения;
IN comm - коммуникатор;
OUT status - атрибуты опрошенного сообщения.

Подпрограмма MPI_Probe выполняется с блокировкой, поэтому завершится она лишь тогда, когда сообщение с подходящим идентификатором и номером процесса-отправителя будет доступно для получения. Атрибуты этого сообщения возвращаются в переменной status. Следующий за MPI_Probe вызов MPI_Recv с теми же атрибутами сообщения (номером процесса-отправителя, идентификатором сообщения и коммуникатором) поместит в буфер приема именно то сообщение, наличие которого было опрошено подпрограммой MPI_Probe.

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

CALL MPI_COMM_RANK(comm, rank, ierr)IF (rank.EQ.0) THEN CALL MPI_RECV(recvbuf, count, MPI_REAL, 1, tag, comm, status, ierr) CALL MPI_SEND(sendbuf, count, MPI_REAL, 1, tag, comm, ierr)ELSE IF (rank.EQ.1) THEN CALL MPI_RECV(recvbuf, count, MPI_REAL, 0, tag, comm, status, ierr) CALL MPI_SEND(sendbuf, count, MPI_REAL, 0, tag, comm, ierr)END IF

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

Приведем вариант правильной программы.

CALL MPI_COMM_RANK(comm, rank, ierr)IF (rank.EQ.0) THEN CALL MPI_SEND(sendbuf, count, MPI_REAL, 1, tag, comm, ierr) CALL MPI_RECV(recvbuf, count, MPI_REAL, 1, tag, comm, status, ierr)ELSE IF (rank.EQ.1) THEN CALL MPI_RECV(recvbuf, count, MPI_REAL, 0, tag, comm, status, ierr) CALL MPI_SEND(sendbuf, count, MPI_REAL, 0, tag, comm, ierr)END IF

Другие комбинации операций SEND/RECV могут работать или не работать в зависимости от реализации MPI (буферизованный обмен или нет).

В ситуациях, когда требуется выполнить взаимный обмен данными между процессами, безопаснее использовать совмещенную операцию MPI_Sendrecv.

С:

int MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,

int dest, int sendtag, void *recvbuf, int recvcount,

MPI_Datatype recvtype, int source, MPI_Datatypeа recvtag,

MPI_Comm comm, MPI_Status *status)

FORTRAN:

MPI_SENDRECV(SENDBUF, SENDCOUNT, SENDTYPE, DEST, SENDTAG, RECVBUF,

RECVCOUNT, RECVTYPE, SOURCE, RECVTAG, COMM, STATUS, IERROR)

<type> SENDBUF(*), RECVBUF(*)

INTEGER SENDCOUNT, SENDTYPE, DEST, SENDTAG, RECVCOUNT, RECVTYPE,

SOURCE, RECV TAG, COMM, STATUS(MPI_STATUS_SIZE), IERROR

IN sendbuf - адрес начала расположения посылаемого сообщения;
IN sendcount - число посылаемых элементов;
IN sendtype - тип посылаемых элементов;
IN dest - номер процесса-получателя;
IN sendtag - идентификатор посылаемого сообщения;
OUT recvbuf - адрес начала расположения принимаемого сообщения;
IN recvcount - максимальное число принимаемых элементов;
IN recvtype - тип элементов принимаемого сообщения;
IN source - номер процесса-отправителя;
IN recvtag - идентификатор принимаемого сообщения;
IN comm - коммуникатор области связи;
OUT status - атрибуты принятого сообщения.

Функция MPI_Sendrecv совмещает выполнение операций передачи и приема. Обе операции используют один и тот же коммуникатор, но идентификаторы сообщений могут различаться. Расположение в адресном пространстве процесса принимаемых и передаваемых данных не должно пересекаться. Пересылаемые данные могут быть различного типа и иметь разную длину. В тех случаях, когда необходим обмен данными одного типа с замещением посылаемых данных на принимаемые, удобнее пользоваться функцией MPI_Sendrecv_replace.

С:

MPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype,

int dest, int sendtag, int source, int recvtag,

MPI_Comm comm, MPI_Status *status)

FORTRAN:

MPI_SENDRECV_REPLACE(BUF, COUNT, DATATYPE, DEST,

SENDTAG, SOURCE, RECVTAG, COMM, STATUS, IERROR)

<type> BUF(*)

INTEGER COUNT, DATATYPE, DEST, SENDTAG, SOURCE, RECVTAG, COMM,

STATUS(MPI_STATUS_SIZE), IERROR

INOUT buf - адрес начала расположения посылаемого и принимаемого сообщения;
IN count - число передаваемых элементов;
IN datatype - тип передаваемых элементов;
IN dest - номер процесса-получателя;
IN sendtag - идентификатор посылаемого сообщения;
IN source - номер процесса-отправителя;
IN recvtag - идентификатор принимаемого сообщения;
IN comm - коммуникатор области связи;
OUT status - атрибуты принятого сообщения.

В данной операции посылаемые данные из массива buf замещаются принимаемыми данными.

В качестве адресатов source и dest в операциях пересылки данных можно использовать специальный адрес MPI_PROC_NULL. Коммуникационные операции с таким адресом ничего не делают. Применение этого адреса бывает удобным вместо использования логических конструкций для анализа условий посылать/читать сообщение или нет. Этот прием будет использован нами далее в одном из примеров, а именно, в программе решения уравнения Лапласа методом Якоби.







Дата добавления: 2015-09-15; просмотров: 379. Нарушение авторских прав; Мы поможем в написании вашей работы!



Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Композиция из абстрактных геометрических фигур Данная композиция состоит из линий, штриховки, абстрактных геометрических форм...

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

ТЕОРЕТИЧЕСКАЯ МЕХАНИКА Статика является частью теоретической механики, изучающей условия, при ко­торых тело находится под действием заданной системы сил...

Огоньки» в основной период В основной период смены могут проводиться три вида «огоньков»: «огонек-анализ», тематический «огонек» и «конфликтный» огонек...

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

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

ЛЕКАРСТВЕННЫЕ ФОРМЫ ДЛЯ ИНЪЕКЦИЙ К лекарственным формам для инъекций относятся водные, спиртовые и масляные растворы, суспензии, эмульсии, ново­галеновые препараты, жидкие органопрепараты и жидкие экс­тракты, а также порошки и таблетки для имплантации...

Тема 5. Организационная структура управления гостиницей 1. Виды организационно – управленческих структур. 2. Организационно – управленческая структура современного ТГК...

Методы прогнозирования национальной экономики, их особенности, классификация В настоящее время по оценке специалистов насчитывается свыше 150 различных методов прогнозирования, но на практике, в качестве основных используется около 20 методов...

Studopedia.info - Студопедия - 2014-2024 год . (0.033 сек.) русская версия | украинская версия