Лабораторная работа 9,10,11,12 Группа 22120 kif бекпулатов Жавлонбек
Скачать 272.77 Kb.
|
Лабораторная работа №10 Изучение работы пакета MPI Цель работы: изучить структуру стандарта программирования системы MPI (Message Passing Interface) и продемонстрировать ряд функций её библиотеки Краткие характеристики. MPI - это стандарт на программный инструментарий для обеспечения связи между ветвями параллельного приложения. MPI расшифровывается как "Message passing interface" ("Взаимодействие через передачу сообщений"). Несколько путает дело тот факт, что этот термин уже применяется по отношению к аппаратной архитектуре ЭВМ. Программный инструментарий MPI реализован в том числе и для ЭВМ с такой архитектурой. MPI предоставляет программисту единый механизм взаимодействия ветвей внутри параллельного приложения независимо от машинной архитектуры (однопроцессорные / многопроцессорные с общей/раздельной памятью), взаимного расположения ветвей (на одном процессоре / на разных) и API операционной системы. ( API = "applications programmers interface" = "интерфейс разработчика приложений" ) Программа, использующая MPI, легче отлаживается (сужается простор для совершения стереотипных ошибок параллельного программирования) и быстрее переносится на другие платформы (в идеале, простой перекомпиляцией). В настоящее время разными коллективами разработчиков написано несколько программных пакетов, удовлетворяющих спецификации MPI, в частности: MPICH, LAM, HPVM и так далее. Они выступают базовыми при переносе MPI на новые архитектуры ЭВМ. Здесь в пособии рассматриваются разновидности MPICH. Это сделано по двум причинам: MPICH написан авторами спецификации, и наиболее распространен. Таким образом, далее по тексту термин MPI используется не только для обозначения изложенных в спецификации сведений, но и, в определенной мере, для описания характеристик конкретной базовой реализации. Увы. Минимально в состав MPI входят: библиотека программирования (заголовочные и библиотечные файлы для языков Си, Си++ и Фортран) и загрузчик приложений. Дополнительно включаются: профилирующий вариант библиотеки (используется на стадии тестирования параллельного приложения для определения оптимальности распараллеливания); загрузчик с графическим и сетевым интерфейсом для X-Windows и проч. Структура каталогов MPICH выполнена в полном соответствии с традициями Юникса: bin, include, lib, man, src, ... Минимальный набор функций прост в освоении и позволяет быстро написать надежно работающую программу. Использование же всей мощи MPI позволит получить БЫСТРО работающую программу - при сохранении надежности. Первоначально весь текст данного пособия был собран в одном документе. Теперь он разбит на три части: вводно-философская часть: сравнительные характеристики MPI, его плюсы и минусы, сильные и слабые стороны, прошлое и будущее, стихи и проза, лед и пламень, ... руководство пользователя по нескольким реализациям MPI: MPICH, WinMPICH, WMPI, PowerMPI и HPMPI; ссылки на документацию, в т.ч. по MPICH руководство программиста - оставлено здесь. Рекомендуется читать их именно в таком порядке. Некоторые сведения, к сожалению, повторяются, потому что разделение первоначального текста на части было выполнено несколько поспешно. Соглашения о терминах. Параллельное приложение состоит из нескольких ветвей, или процессов, или задач, выполняющихся одновременно. Разные процессы могут выполняться как на разных процессорах, так и на одном и том же - для программы это роли не играет, поскольку в обоих случаях механизм обмена данными одинаков. Процессы обмениваются друг с другом данными в виде сообщений. Сообщения проходят под идентификаторами, которые позволяют программе и библиотеке связи отличать их друг от друга. Для совместного проведения тех или иных расчетов процессы внутри приложения объединяются в группы. Каждый процесс может узнать у библиотеки связи свой номер внутри группы, и, в зависимости от номера приступает к выполнению соответствующей части расчетов. Термин "процесс" используется также в Юниксе, и здесь нет путаницы: в MPI ветвь запускается и работает как обычный процесс Юникса, связанный через MPI с остальными процессами, входящими в приложение. В остальном процессы следует считать изолированными друг от друга: у них разные области кода, стека и данных (короче, смотрите описание Юниксовских процессов). Говорят, что процессы имеют раздельную память (separate memory). Особенность MPI: понятие области связи (communication domains). При запуске приложения все процессы помещаются в создаваемую для приложения общую область связи. При необходимости они могут создавать новые области связи на базе существующих. Все области связи имеют независимую друг от друга нумерацию процессов. Программе пользователя в распоряжение предоставляется коммуникатор - описатель области связи. Многие функции MPI имеют среди входных аргументов коммуникатор, который ограничивает сферу их действия той областью связи, к которой он прикреплен. Для одной области связи может существовать несколько коммуникаторов таким образом, что приложение будет работать с ней как с несколькими разными областями. В исходных текстах примеров для MPI часто используется идентификатор MPI_COMM_WORLD. Это название коммуникатора, создаваемого библиотекой автоматически. Он описывает стартовую область связи, объединяющую все процессы приложения. Категории функций: блокирующие, локальные, коллективные. В manual pages особо подчеркивается принадлежность описываемой функции к той или иной категории. При первом чтении этот раздел можно пропустить, возвращаясь к нему по мере ознакомления с документацией. Вкратце: Блокирующие - останавливают (блокируют) выполнение процесса до тех пор, пока производимая ими операция не будет выполнена. Неблокирующие функции возвращают управление немедленно, а выполнение операции продолжается в фоновом режиме; за завершением операции надо проследить особо. Неблокирующие функции возвращают квитанции ("requests"), которые погашаются при завершении. До погашения квитанции с переменными и массивами, которые были аргументами неблокирующей функции, НИЧЕГО ДЕЛАТЬ НЕЛЬЗЯ. Локальные - не инициируют пересылок данных между ветвями. Большинство информационных функций является локальными, т.к. копии системных данных уже хранятся в каждой ветви. Функция передачи MPI_Send и функция синхронизации MPI_Barrier НЕ являются локальными, поскольку производят пересылку. Следует заметить, что, к примеру, функция приема MPI_Recv (парная для MPI_Send) является локальной: она всего лишь пассивно ждет поступления данных, ничего не пытаясь сообщить другим ветвям. Коллективные - должны быть вызваны ВСЕМИ ветвями-абонентами того коммуникатора, который передается им в качестве аргумента. Несоблюдение для них этого правила приводит к ошибкам на стадии выполнения программы (как правило, к повисанию). Принятая в MPI нотация записи. Регистр букв : важен в Си, не играет роли в Фортране. Все идентификаторы начинаются с префикса "MPI_". Это правило без исключений. Не рекомендуется заводить пользовательские идентификаторы, начинающиеся с этой приставки, а также с приставок "MPID_", "MPIR_" и "PMPI_", которые используются в служебных целях. Если идентификатор сконструирован из нескольких слов, слова в нем разделяются подчерками: MPI_Get_count, MPI_Comm_rank. Иногда, однако, разделитель не используется: MPI_Sendrecv, MPI_Alltoall. Порядок слов в составном идентификаторе выбирается по принципу "от общего к частному": сначала префикс "MPI_", потом название категории ( Type, Comm, Group, Attr, Errhandler и т.д.), потом название операции ( MPI_Errhandler_create, MPI_Errhandler_set, ...). Наиболее часто употребляемые функции выпадают из этой схемы: они имеют "анти-методические", но короткие и стереотипные названия, например MPI_Barrier, или MPI_Unpack. Имена констант (и неизменяемых пользователем переменных) записываются полностью заглавными буквами: MPI_COMM_WORLD, MPI_FLOAT. В именах функций первая за префиксом буква - заглавная, остальные маленькие: MPI_Send, MPI_Comm_size. Такая нотация по первому времени может показаться непривычной, однако ее использование быстро входит в навык. Надо признать, что она делает исходные тексты более читабельными. MPI для Фортрана. Здесь в сжатом виде изложены основные отличия особенности реализации MPI для Фортрана. С их учетом программисты, пишущие на языке Фортран, смогут приступить к изучению дальнейшего материала. Регистр символов в исходном тексте для Фортрана значения не имеет. MPI_Comm_rank и MPI_COMM_RANK для него, в отличие от Си, является одним и тем же идентификатором. В начале исходного текста должна быть строка include 'mpif.h' Этот файл содержит описания переменных и констант. Все, что в Си является функциями, в Фортране сделано подпрограммами. В Си код ошибки MPI возвращается пользовательской программе как код завершения функции; в Фортране код ошибки возвращается в дополнительном параметре: Си: errcode = MPI_Comm_rank( MPI_COMM_WORLD, &rank ); Фортран: CALL MPI_COMM_RANK ( MPI_COMM_WORLD, rank, ierror ) Все параметры в Фортране передаются не по значению, а по ссылке. Соответственно, там, где в Си используется символ "&" для вычисления адреса переменной, в Фортране не надо писать ничего. Это иллюстрирует пример для предыдущего пункта, где в переменную rank функция/подпрограмма записывает номер вызвавшей ее задачи.Там, где MPI требуется знать местонахождение в памяти таких данных, которые по ссылке не передашь (например, при конструировании пользовательских типов), используется подпрограмма MPI_ADDRESS. В Фортране нет структур. Там, где в Си для описания данных в MPI применяется структура, в Фортране применяется целочисленный массив, размер и номера ячеек которого описаны символическими константами: В Си пишем:MPI_Status status; /* переменная типа структура */ MPI_Probe( MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status ); /* теперь проверяем поля заполненной структуры */ if( status.MPI_SOURCE == 1 ) { ... } if( status.MPI_TAG == tagMsg1 ) { ... } В Фортране, соответственно:INTEGER status(MPI_STATUS_SIZE) CALL MPI_PROBE( MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD, status ) IF( status(MPI_SOURCE) .EQ. 1 ) .... IF( status(MPI_TAG) .EQ. tagMsg1 ) ...ну и так далее... Грубо говоря: имя типа-структуры переходит в размер массива, дополняясь суффиксом "_SIZE", а имена полей переходят в индексы ячеек в этом целочисленном массиве. Для компиляции и компоновки вместо команды ' |