Модель системы с передачей сообщений. MPI-библиотеки, страница 2

Главными компонентами любой MPI-библиотеки являются функции взаимодействия, осуществляющие обмен данными между двумя процессами. Обычно такие функции называют send и recv. Базовые вызовы могут выглядеть следующим образом:

send(address, length, destination, tag)

recv(address, max_length, source, tag, rec_length)

Здесь параметры означают следующее:

address - место в памяти, где расположен буфер, содержащий посылаемые или принимаемые данные.

length - длина посылаемого сообщения (обычно в байтах).

max_length - длина буфера, в который будет записано принимаемое сообщение.

rec_length - длина фактически принятого пакета данных.

destination - идентификатор процесса-приемника.

source - как выходной параметр показывает, откуда послано сообщение;

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

tag - произвольное (обычно неотрицательное) число, позволяющее идентифицировать каждое сообщение.

Обычно MPI-библиотека содержит как коммуникации с блокировкой, так и без нее.

Взаимодействия с блокировкой

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

Recv - завершается после того как буфер этой функции готов для использования.

Взаимодействия с блокировкой являются простейшими, однако они могут оказаться небезопасными. Завершение процесса обмена зависит от размера сообщения и объема системных буферов. Если размер сообщения превосходит размер доступных системных буферов, функция send может не закончиться.

Process 0             Process 1    Тогда в коде на рисунке в процессе 0

bsend(1)              bsend(0)            функция brecv(1) может оказаться

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

Небезопасные программы следует рассматривать как некорректные и программист должен предпринять определенные шаги, чтобы гарантировать правильное исполнение алгоритма. Способами решения проблемы могут являться:

1) перестановка операций;    Process 0                     Process 1

bsend(1)              brecv(0)

brecv(1)              bsend(0)

2) если библиотека позволяет, можно воспользоваться функцией одновременной передачи-приема сообщения sendrecv:

Process 0             Process 1

sendrecv(1)   sendrecv(0)

3) использование неблокирующих операций (см. ниже)

Process 0             Process 1

nbsend(1)            nbsend(0)

nbrecv(1)            nbrecv(0)

waitall                 waitall

Взаимодействия без блокировки

Основными отличиями функций этого типа взаимодействий является:

- возвращаются немедленно;

- позволяют совмещать обмен сообщениями и проведение вычислений (буферы не должны использоваться до завершения операций обмена);

- функции ожидания гарантируют окончание обмена;

- обычно возвращают идентификатор сообщения, который после используется функцией ожидания;

Главные вызовы функций взаимодействия без блокировки могут выглядеть следующим образом:

nbsend(address, length, destination, tag, msg_id) nbrecv(adress,max_length, source, tag, msg_id) wait(msg_id)

Дополнительные операции

Некоторые MPI-библиотеки могут предоставлять различные дополнительные функции обмена сообщениями. Наиболее распространенными являются следующие:

Синхронный send - send не завершает свою работу, пока не начнет свою работу соответствующий этому send вызов recv.

Буферизованный send - пользователь предоставляет системе буфер для того, чтобы гарантировать безопасность программы. Данные типы функций могут представляться как в форме с блокировкой, так и без нее.

Оба типа дополнительных функций вносят отрицательный вклад, приводя к снижению производительности системы. Синхронные коммуникации могут быть причиной длительного ожидания прихода сообщения, а также тупиков в случае, когда соответствующая операция recv является недостижимой. Буферизованный send повышает накладные расходы при каждой посылке и, тем самым, снижает пропускную способность канала. В целом такие функции следует исключать из вычислительного процесса.

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

Групповой обмен