Н.В. Вдовикина, А.В. Казунин, И.В. Машечкин, А.Н. Техехин - Системное программное обеспечение - взаимодействие процессов (1114927), страница 25
Текст из файла (страница 25)
*/155задачвзапущенномMPI_Comm_rank (MPI_COMM_WORLD, &rank);/* ...и свой собственный номер: от 0 до (size1) *//* задача с номером 0 сообщает пользователюразмер группы,коммуникационный контекст которойописываеткоммуникаторMPI_COMM_WORLD,т.е.число ветвей в приложении */if (rank == 0) {printf("Totalsize );processescount=%d\n",}/* Осуществляется барьерная синхронизация*/MPI_Barrier(MPI_COMM_WORLD);/* Теперь каждая задача выводит на экран свойномер */printf("Hello!%d\n", rank);MyrankinMPI_COMM_WORLD/* Осуществляется барьерная синхронизация=*/MPI_Barrier(MPI_COMM_WORLD);/* затем ветвь c номером 0 печатает аргументыкомандной строки. */if (rank == 0) {printf(“Command line of process 0:\n");for(i = 0; i < argc; i++) {printf("%d: \"%s\"\n", i, argv[i]);}}/* Все задачи завершают выполнение */MPI_Finalize();return 0;}7.2.4 Прием и передача данных.
Общие замечания.Преждечемперейтикрассмотрениюфункций,непосредственно относящихся к организации обмена сообщениямимежду ветвями, остановимся на некоторых важных общих156моментах, таких как атрибуты сообщения и поддержка типизацииданных в MPI.Сообщения и их атрибуты.Каждое сообщение MPI обладает следующим набороматрибутов:- Номер ветви-отправителя- Номер или номера ветвей-получателей- Коммуникатор, т.е. описатель коммуникационногоконтекста, в котором данное сообщение передается- Тип данных, образующих тело сообщения- Количествоэлементовуказанногосоставляющих тело сообщениятипа,- Тэг, или бирка сообщенияВ MPI не существует специальной структуры данных,описывающей сообщение. Вместо этого, атрибуты сообщенияпередаются в соответствующие функции и получаются из них какотдельные параметры.Тэг сообщения представляет собой целое число, аналог типасообщения в механизме очередей сообщений IPC.
Интерпретацияэтого атрибута целиком возлагается на саму программу.Поддержка типов данных в MPI.В отличие от других средств межпроцессного взаимодействия,рассмотренных нами ранее, в MPI требуется явное указание типаданных, образующих тело сообщения. Причина этого заключается втом, что библиотека MPI берет на себя заботу о корректностипередачи данных в случае использования ее в гетерогенной (т.е.состоящей из разнородных узлов) среде. Одни и те же типы данныхна машинах разных архитектур могут иметь различноепредставление (к примеру, в архитектуре Intel представление целыхчисел характеризуется расположением байт от младшего кстаршему, в то время как в процессорах Motorola принято обратноерасположение; кроме того, на разных машинах один и тот же типможет иметь разную разрядность и выравнивание). Очевидно, что втакой ситуации передача данных как последовательности байт безсоответствующих преобразований приведет к их невернойинтерпретации.
Реализация MPI производит необходимыепреобразования данных в теле сообщения перед его посылкой и157после получения, однако для этого необходима информация о типеданных, образующих тело сообщения.Для описания типов данных в MPI введен специальный тип –MPI_Datatype. Для каждого стандартного типа данных Си взаголовочном файле библиотеки описана константа типаMPI_Datatype; ее имя состоит из префикса MPI_ и имени типа,написанного большими буквами, например, MPI_INT, MPI_DOUBLE ит.д. Кроме этого, MPI предоставляет широкие возможности поконструированию описателей производных типов, однако ихрассмотрение выходит за рамки данного пособия.Параметр типа MPI_Datatype, описывающий тип данных,образующих тело сообщения, присутствует во всех функцияхприема и передачи сообщений MPI.Непосредственно с поддержкой типов данных MPI связанаеще одна особенность функций приема-передачи данных: в качестверазмера тела сообщения всюду фигурирует не количество байт, аколичество элементов указанного типа.7.2.5 Коммуникациирежим.«точка-точка».БлокирующийБиблиотека MPI предоставляет возможности для организациикак индивидуального обмена сообщениями между парой ветвей – вэтом случае у каждого сообщения имеется единственный получатель– так и коллективных коммуникаций, в которых участвуют всеветви, входящие в определенный коммуникационный контекст.Рассмотрим сначала функции MPI, используемые дляотправки и получения сообщений между двумя ветвями – такойспособ обмена в литературе часто носит название коммуникации«точка-точка».Библиотека MPI предоставляет отдельные пары функций дляреализации блокирующих и неблокирующих операций приема ипосылки данных.
Заметим, что они совместимы друг с другом влюбых комбинациях, например, для отправки сообщения можетиспользоваться блокирующая операция, а для приема этого жесообщения – неблокирующая, и наоборот.Отправка сообщений в блокирующем режиме.Для отправки сообщений в блокирующем режиме служитфункция MPI_Send():#include <mpi.h>158int MPI_Send(void* buf, int count, MPI_Datatypedatatype, int dest, int tag, MPI_Comm comm);Аргументы у этой функции следующие:buf – указатель на буфер, в котором расположеныданные для передачиcount – количество элементов заданного типа в буфереdatatype – тип элементов в буфере–уникальныйномерветви-получателя.Представляет собой неотрицательное целое число в диапазоне[0, N-1], где N – число ветвей в коммуникационном контексте,описываемом коммуникатором commdesttag – тэг (бирка) сообщения.
Представляет собойнеотрицательное целое число от 0 до некоторого максимума,значение которого зависит от реализации (однако стандартMPI гарантирует, что этот максимум имеет значение не менее32767). Тэги сообщений могут использоваться ветвями длятого, чтобы отличать разные по смыслу сообщения друг отдруга.–коммуникатор,описывающийкоммуникационный контекст, в котором будет передаватьсясообщениеcommЕще раз отметим, что в этой функции, как и во всех остальныхфункциях приема-передачи MPI, в параметре count указывается недлина буфера в байтах, а количество элементов типа datatype,образующих буфер.При вызове MPI_Send() управление возвращается процессутолько тогда, когда вызвавший процесс может повторноиспользовать буфер buf (т.е.
записывать туда другие данные) безриска испортить еще не переданное сообщение. Однако, возврат изфункции MPI_Send() не обязательно означает, что сообщение былодоставлено адресату – в реализации данной функции можетиспользоваться буферизация, т.е. тело сообщения может бытьскопировано в системный буфер, после чего происходит возврат изMPI_Send(), а сама передача будет происходить позднее васинхронном режиме.С одной стороны, буферизация при отправке позволяет ветвиотправителю сообщения продолжить выполнение, не дожидаясьмомента, когда ветвь-адресат сообщения инициирует его прием; сдругой стороны – буферизация, очевидно, увеличивает накладные159расходы как по памяти, так и по времени, так как требуетдобавочного копирования.
При использовании вызова MPI_Send()решение о том, будет ли применяться буферизация в каждомконкретном случае, принимается самой библиотекой MPI. Эторешениепринимаетсяизсоображенийнаилучшейпроизводительности, и может зависеть от размера сообщения, атакже от наличия свободного места в системном буфере. Еслибуферизация не будет применяться, то возврат управления изMPI_Send() произойдет только тогда, когда ветвь-адресатинициирует прием сообщения, и его тело будет скопировано вбуфер-приемник ветви-адресата.Режимы буферизации.MPI позволяет программисту самому управлять режимомбуферизации при отправке сообщений в блокирующем режиме. Дляэтого в MPI существуют три дополнительные модификациифункции MPI_Send(): MPI_Bsend(), MPI_Ssend() и MPI_Rsend():#include <mpi.h>int MPI_Bsend(void* buf, int count, MPI_Datatypedatatype, int dest, int tag, MPI_Comm comm);int MPI_Ssend(void* buf, int count, MPI_Datatypedatatype, int dest, int tag, MPI_Comm comm);int MPI_Rsend(void* buf, int count, MPI_Datatypedatatype, int dest, int tag, MPI_Comm comm);Их параметры полностью аналогичны MPI_Send(), различиезаключается только в режимах буферизации.предполагаетотсылкусообщениясбуферизацией.
Это означает, что если к моменту вызоваMPI_Bsend() ветвь-адресат не инициировала прием сообщения, ит.о. сообщение не может быть доставлено немедленно, оно должнобыть буферизовано. Если в буфере окажется недостаточносвободного места, MPI_Bsend() вернет ошибку. MPI предоставляетспециальные функции, с помощью которых ветвь может выделить всвоем адресном пространстве некоторый буфер, который будетиспользоваться MPI для буферизации сообщений в этом режиме,таким образом, программист может сам управлять размеромдоступного буферного пространства.
Заметим, что посылкасообщения с помощью функции MPI_Bsend() является, в отличие отвсех остальных операций отсылки, локальной операцией, т.е. еезавершение не зависит от поведения ветви-адресата.MPI_Bsend()160Функция MPI_Ssend(), наоборот, представляет собой отсылкусообщения без буферизации. Возврат управления из функцииMPI_Ssend() осуществляется только тогда, когда адресатинициировал прием сообщения, и оно скопировано в буферприемник адресата.
Если на принимающей стороне используетсяблокирующая функция приема сообщения, то такая коммуникацияпредставляет собой реализацию схемы рандеву: операция обмена,инициированная на любой из сторон, не завершится до тех пор, покавторая сторона также не притупит к обмену.Вызов функции MPI_Rsend() сообщает MPI о том, что ветвьадресат уже инициировала запрос на прием сообщения. В некоторыхслучаях знание этого факта позволяет MPI использовать болеекороткий протокол для установления соединения и тем самымповыситьпроизводительностьпередачиданных.Однако,использование этой функции ограничено теми ситуациями, когдаветви-отправителю известно о том, что ветвь-адресат уже ожидаетсообщение.