Спец часть (часть 3) (3 поток) (2015) (by Кибитова) (1161603), страница 48
Текст из файла (страница 48)
Кроме того, для разблокировки необходимо, чтобы все синхронизируемые нитизавершили все порождённые ими задачи (task). l. 416Следующий пример демонстрирует применение директивы barrier. Директива barrier используетсядля упорядочивания вывода от работающих нитей. Выдачи с разных нитей "Сообщение 1"и"Сообщение 2"могут перемежаться в произвольном порядке, а выдача "Сообщение 3"со всех нитейпридёт строго после двух предыдущих выдач.
l. 418#include <stdio.h>#include <omp.h>int main(int argc, char *argv[]){#pragma omp parallel{printf("Сообщение 1\n");printf("Сообщение 2\n");#pragma omp barrierprintf("Сообщение 3\n");}} Основная цель:Основная цель:• Обеспечение переносимости исходных кодов• Эффективная реализация• Обеспечение переносимости исходны• того:Эффективная реализацияКроме◦ Большая функциональность◦ Поддержка неоднородных параллельныхархитектурКроме того:◦ Большая функциональность◦ Поддержканеоднородных параллельнMPI реализуетпередачу сообщений междупроцессами.архитектурМежпроцессное взаимодействие предполагает:Параллельная программа состоит изпроцессов, процессы могут бытьмногопоточными.◦ синхронизацию◦ перемещение данных из адресного пространстваодного процесса в адресное пространство другогопроцесса.
Процессы объединяются в группы.Каждое сообщение посылается в рамкахнекоторого контекста и должно бытьполучено в том же контексте.Группа и контекст вместе определяюткоммуникатор.Процесс идентифицируется своим номеромв группе, ассоциированной скоммуникатором.Коммуникатор, содержащий все начальныепроцессы, называется MPI_COMM_WORLD.Управляющий объект, представляющий группупроцессов, которые могут взаимодействовать другс другомВсе обращения к MPI функциям содержаткоммуникатор, как параметрНаиболее часто используемый коммуникаторMPI_COMM_WORLDОпределяется при вызове MPI_InitСодержит ВСЕ процессы программы Данные в сообщении описываются тройкой:(address, count, datatype), где datatypeопределяетсярекурсивнокак:тройкой:Данные в сообщенииописываютсяДанныев сообщенииописываютсятройкой:(address,count, datatype),где datatype(address,count,datatype),гдеdatatypeрекурсивнокак: тип, соответствующий типу◦определяетсяПредопределенныйбазовыйопределяетсярекурсивнокак: данных в базовом языке (например, MPI_INT,◦ MPI_DOUBLE_PRECISION)Предопределенный базовый тип, соответствующий типу◦ Предопределенныйбазовыйтип, соответствующийтипуданных в базовоммассивязыке(например,MPI_INT,◦ данныхНепрерывныйMPI типовв базовом языке (например,MPI_INT,MPI_DOUBLE_PRECISION)◦◦ MPI_DOUBLE_PRECISION)ВекторныйНепрерывныйтипмассив MPI типов◦◦◦ Непрерывныймассив MPIтиповИндексированыыйтипВекторный тип◦◦ ВекторныйтипИндексированыыйструктурытипПроизвольные◦◦ Индексированыыйтип◦ Произвольные структуры◦ Произвольные структуры MPIвключаетфункциидляпостроенияMPIвключаетвключаетфункциидляпостроенияпостроенияMPIфункциидляпользовательскихтиповданных,например,пользовательскихтиповтиповданных,например,типапользовательскихданных,например,типаданных,описывающихпары(int,float).данных,описывающихпары(int,float).данных, описывающих пары (int, float).MPI datatypeC datatypeMPI_CHARsigned charMPI_SHORTsigned short intMPI_INTsigned intMPI_LONGsigned long intMPI_UNSIGNED_CHARunsigned charMPI_UNSIGNED_SHORTunsigned short intMPI_UNSIGNEDunsigned intMPI_UNSIGNED_LONGunsigned long intMPI_FLOATfloatMPI_DOUBLEdoubleMPI_LONG_DOUBLElong doubleСообщение сопровождается определяемымпользователем признаком дляидентификации принимаемого сообщенияТеги сообщений у отправителя иполучателя должны быть согласованы.Можно указать в качестве значения тэгаконстанту MPI_ANY_TAG.Некоторые не-MPI системы передачисообщений называют тэг типом сообщения.MPI вводит понятие тэга, чтобы не путатьэто понятие с типом данных MPI.
типа error = MPI_Xxxxx(parameter,...);MPI_Xxxxx(parameter,...);Возвращаемое значение – код ошибки. Определяетсяконстантой MPI_SUCCESSint error;......error = MPI_Init(&argc, &argv));if (error != MPI_SUCCESS){fprintf (stderr, “ MPI_Init error \n”);return 1;}#include <mpi.h>main(int argc, char **argv){int numtasks, rank;MPI_Init(&argc, &argv);MPI_Comm_size(MPI_COMM_WORLD, &numtasks);MPI_Comm_rank(MPI_COMM_WORLD, &rank);printf("Hello World from process %d of %d\n“,rank, numtasks);MPI_Finalize();}При запуске указываем число требуемыхпроцессоров np и название программыmpirun –np 3 progНа выделенных для расчета узлах запускается npкопий указанной программыКаждая копия программы получает два значения:◦ np◦ rank из диапазона [0 ...
np-1]Любые две копии программы могутнепосредственно обмениваться данными спомощью функций передачи сообщений int MPI_Init(int *argc, char ***argv)должна первым вызовом, вызывается только один разint MPI_Comm_size(MPI_Comm comm, int *size)число процессов в коммуникатореint MPI_Comm_rank(MPI_Comm comm, int *rank)номер процесса в коммуникаторе (нумерация с 0)int MPI_Finalize()завершает работу процессаint MPI_Abort (MPI_Comm_size(MPI_Comm comm, int*errorcode)завершает работу программыСодержит:Source: status.MPI_SOURCETag: status.MPI_TAGCount: MPI_Get_count В двухточечном обмене участвуют толькодва процесса, процесс-отправитель ипроцесс-получатель (источник сообщенияи адресат).Двухточечные обмены используются дляорганизации локальных инеструктурированных коммуникаций.
Двухточечный обмен возможен только междупроцессами, принадлежащими одной областивзаимодействия (одному коммуникатору).Двухточечный обмен возможен только междупроцессами, принадлежащими одной областивзаимодействия (одному коммуникатору).Отправитель должен указать правильныйrank получателяПолучатель должен указать верный rankотправителяОдинаковый коммуникаторТэги должны соответствовать друг другуБуфер у процесса-получателя должен бытьдостаточного объемаблокирующие прием/передача, которыеприостанавливают выполнение процесса на времяприема или передачи сообщения;неблокирующие прием/передача, при которыхвыполнение процесса продолжается в фоновомрежиме, а программа в нужный момент можетзапросить подтверждение завершения приемасообщения;синхронный обмен, который сопровождаетсяуведомлением об окончании приема сообщения;асинхронный обмен, который таким уведомлениемне сопровождается.
Правильно организованный двухточечныйобмен сообщениями должен исключатьвозможность блокировки или некорректнойработы параллельной MPI-программы.Примеры ошибок в организации двухточечныхобменов:выполняется передача сообщения, но не выполняется егоприем;процесс-источник и процесс-получатель одновременнопытаютсявыполнить блокирующие передачу или приемсообщения.В MPIпринятыследующиесоглашенияоб именахподпрограммВ MPIпринятыследующиесоглашенияоб именахподпрограммдвухточечногообмена:двухточечногообмена:MPI_[I][R,B]SendMPI_[I][R,S, S,B]Sendздесьпрефикс[I](Immediate)обозначаетнеблокирующийрежим.здесь префикс [I] (Immediate)обозначаетнеблокирующийрежим.ОдинпрефиксовB] обозначаетрежимобмена:по готовности,Одиниз изпрефиксов[R,[R,S, S,B] обозначаетрежимобмена:по готовности,синхронныйи буферизованный.синхронныйи буферизованный.Отсутствиепрефиксаобозначаетподпрограммустандартногообмена.Отсутствие префикса обозначаетподпрограммустандартногообмена.Имеется8разновидностейоперациипередачисообщений.Имеется 8 разновидностей операции передачи сообщений.Дляподпрограммприема:Дляподпрограммприема:MPI_[I]RecvMPI_[I]Recvестьвсего2 разновидностиприема.то тоестьвсего2 разновидностиприема.ПодпрограммаMPI_Irsend,например,выполняетпередачу«по «поПодпрограммаMPI_Irsend,например,выполняетпередачуготовности»в неблокирующемрежиме,MPI_Bsendбуферизованнуюготовности»в неблокирующемрежиме,MPI_Bsendбуферизованнуюпередачус блокировкой,а MPI_Recvвыполняетблокирующийприемпередачус блокировкой,а MPI_Recvвыполняетблокирующийприемсообщений.сообщений.Подпрограммаприемалюбоготипаможетпринятьсообщенияот любойПодпрограммаприемалюбоготипаможетпринятьсообщенияот любойподпрограммыпередачи.подпрограммыпередачи.
int MPI_Send(void *buf, int count, MPI_Datatype datatype,intdest, int tag, MPI_Comm comm)MPI_Send(buf, count, datatype, dest, tag, comm, ierr)buf - адрес первого элемента в буфере передачи;count - количество элементов в буфере передачи(допускаетсяcount= 0);Пристандартнойблокирующейпередаче послеdatatype - типMPI (послекаждогопересылаемогоэлемента;завершениявызовавозвратаизфункции/процедурыпередачи) можноdest - ранг процесса-получателясообщения ( целоечисло от 0 долюбыеn - 1, гдеn число процессов в областииспользоватьпеременные,взаимодействия); в списке параметров. Такоеиспользовавшиесяиспользованиене повлияет на корректностьtag - тег сообщения;обмена.comm - коммуникатор;Дальнейшая«судьба» сообщения зависит отierr - код завершения.реализации MPI.
Сообщение может быть сразупередано процессу-получателю или может бытьскопировано в буфер передачи.Завершение вызова не гарантирует доставкисообщения по назначению. Такая гарантияпредоставляется при использовании другихразновидностей двухточечного обмена. int MPI_Recv(void *buf, int count, MPI_Datatype datatype, intsource, int tag, MPI_Comm comm, MPI_Status *status)int MPI_Recv(void *buf, int count, MPI_Datatype datatype, intMPI_Recv(buf,count,datatype, dest,tag, comm,status,ierr)source, inttag, MPI_Commcomm,MPI_Status*status)buf - адрес первого элемента в буфере приёма;MPI_Recv(buf, count, datatype, dest, tag, comm, status, ierr)count - количество элементов в буфере приёма;datatype - тип MPI каждого пересылаемого элемента;buf -- адреспервого элемента в буфереприёма;sourceранг процесса-отправителясообщения( целоеcountколичествов буферев областиприёма;числоот -0 доn - 1, где элементовn число процессоввзаимодействия);datatype - тип MPI каждого пересылаемого элемента;tagsource- тег сообщения;- ранг процесса-отправителя сообщения ( целоеcomm- коммуникатор;числоот 0 до n - 1, где n число процессов в областивзаимодействия);status- статус обмена;ierrtag- кодзавершения.- тегсообщения;comm - коммуникатор;status - статус обмена;ierr - код завершения.
Значение параметра count может оказаться больше, чемколичество элементов в принятом сообщении. В этомслучае после выполнения приёма в буфере изменитсязначение только тех элементов, которые соответствуютэлементам фактически принятого сообщения.Для функции MPI_Recv гарантируется, что послезавершения вызова сообщение принято и размещено вбуфере приема. MPI_ERR_COMM - неправильно указан коммуникатор.Часто возникает при использовании «пустого»коммуникатора;MPI_ERR_COUNT - неправильное значение аргументаcount(количество пересылаемых значений);MPI_ERR_TYPE - неправильное значение аргумента,задающего тип данных;MPI_ERR_TAG - неправильно указан тег сообщения;MPI_ERR_RANK - неправильно указан ранг источникаили адресата сообщения;MPI_ERR_ARG - неправильный аргумент, ошибочноезадание которого не попадает ни в один классошибок;MPI_ERR_REQUEST - неправильный запрос навыполнение операции.В качестве ранга источника сообщения и вкачестве тега сообщения можно использовать«джокеры» :◦ MPI_ANY_SOURCE - любой источник;◦ MPI_ANY_TAG - любой тег.При использовании «джокеров» есть опасностьприема сообщения, не предназначенногоданному процессуПодпрограмма MPI_Recv может приниматьсообщения, отправленные в любом режиме.Прием может выполняться от произвольногопроцесса, а в операции передачи должен бытьуказан вполне определенный адрес.Приемник может использовать «джокеры» дляисточника и для тега.