скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыДипломная работа: Основы параллельного программирования на кластере и разработка элективного курса «Администрирование в информационных системах и администрирование виртуальных машин»

Эффективное программирование для PVM начинается с того, что алгоритм вычислений следует адаптировать к составу PVM и к ее характеристикам. Это очень творческая задача, которая во многих случаях должна решаться программистом. Кроме задачи распараллеливания вычислений с необходимостью возникает и задача управления вычислительным процессом, координации действий задач - участников этого процесса. Иногда для управления приходится создавать специальную задачу, которая сама не участвуя в вычислениях, обеспечивает согласованную работу остальных задач - вычислителей.

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

Наиболее простой и популярный способ организации параллельного счета выглядит следующим образом. Сначала запускается одна задача (master), которая в коллективе задач будет играть функции координатора работ. Эта задача производит некоторые подготовительные действия, например инициализация начальных условий, после чего запускает остальные задачи (slaves), которым может соответствовать либо тот же исполняемый файл, либо разные исполняемые файлы. Такой вариант организации параллельных вычислений предпочтительнее при усложнении логики управления вычислительным процессом, а также когда алгоритмы, реализованные в разных задачах, существенно различаются или имеется большой объем операций (например, ввода - вывода), которые обслуживают вычислительный процесс в целом.

1.6.1 Взаимодействие задач в PVM

В системе PVM каждая задача, запущенная на некотором процессоре, идентифицируется целым числом, которое называется идентификатором задачи (TID) и по смыслу похоже на идентификатор процесса в операционной системе Unix. Система PVM автоматически поддерживает уникальность таких идентификаторов: копии одного исполняемого файла, запущенные параллельно на N процессорах PVM, создают N задач с разными TID.

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

Для повышения эффективности межзадачного обмена информацией предусмотрено использование нескольких алгоритмов. В частности, можно использовать алгоритм блокированной передачи, при котором функция "Послать сообщение" возвращает значение (т.е. завершает работу) только после того как получена положительная или отрицательная квитанция от получателя сообщения. Такой алгоритм передачи с ожиданием уведомления о доставке предпочтителен в тех случаях, когда длинное сообщение передается несколькими порциями, а также при обмене командами, последовательность выполнения которых во времени дорлжна быть строго фиксированной.

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

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

Память для буферных массивов на передающей и приемной стороне выделяется динамически, следовательно, максимальный объем сообщений ограничивается только объемом доступной памяти. Если одна из задач, запущенных в PVM, не может получить требуемую память для общения с другими задачами, то она выдает пользователю соответствующее сообщение об ошибке ("cannot get memory"), но другие задачи об этом событии не извещаются и могут, например, продолжать посылать ей сообщения.

1.6.2 Управление задачами

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

call pvmfmytid( tid )

возвращающую значение идентификатора задачи tid >= 0, которым может определяться выбор для выполнения той или иной части программы. Эта функция может вызываться более одного раза.

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

call pvmfspawn( task, flag, where, ntask, tids, numt )

task - имя исполняемого файла

INTEGER flag   - опции запуска

where - указывает место запуска

INTEGER ntask - число запускаемых копий программы

INTEGER tids - массив значений tid для запущенных задач

Эта функция запускает в PVM ntask копий исполняемого файла с именем "task" с одинаковыми аргументами командной строки в массиве argv и возвращает число запущенных задач numt а также последовательность идентификаторов для запущенных задач. Причем, если numt Второй вариант написания параллельной задачи заключается в том, что для каждого процессора пишутся свои собственные задачи, выполняющие различные действия, и создается маленькая программа, которая, используя функцию pvm_spawn запускает все остальные задачи.

Исполняемый файл для функции pvm_spawn() должен находиться в строго определенном каталоге. Под Unix задача ищется в каталогах $PVM_ROOT/bin/$PVM_ARCH/ и $HOME/pvm3/bin/$PVM_ARCH. Задавать имя каталога в параметре "task" недопустимо.

Но это не единственный способ. В другом варианте исполняемый файл ищется (и запускается) не только на том компьютере, на котором работает вызвавшая pvm_spawn() задача, но в зависимости от параметров flag и where, на любом входящем в состав PVM. Например, если flag==0, то PVM сам выбирает, на какой из машин запускать новые задачи (главное, чтобы приложение было скомпилировано на этих машинах); а если flag & PvmMppFront > 0, то местом запуска будет выбран самый быстрый компьютер.

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

В FORTRANe flag может быть суммой следующих величин:

PVMDEFAULT=0 - PVM может выбрать любую машину для старта задачи

PVMHOST=1 - параметр where определяет машину для запуска

PVMARCH=2 - параметр where определяет тип архитектуры

PVMDEBUG=4 - процесс старует под отладчиком

PVMTRACE=8 - процесс генерирует PVM trace data.

Параметр where описывает на каких компьютерах кластера может быть запущена задача. Параметр является простой строковой переменной, в которую записано имя списка компьютеров. Списки компьютеров находятся в конфигурационных файлах системы PVM и формируются на этаме ее установки. Например в случае, когда в вашем кластере кроме консольной машины присутствует еще два компьютера: один класса P166 и другой класса P4, вы можете определить их в системе под именами "oldcomp" и "supercomp". И в зависимости от тех или иных условий, запускать свои задачи на какой-либо их этих машин кластера.

И, наконец, еще две функции, относящиеся к управлению задачами.

call pvmfkill( tid, info )

call pvmfexit( info )

Первая из них завершает выполнение задачи с идентификатором tid, возвращая при ошибке код ошибки info < 0. Отметим, что задача не может таким образом завершить свое выполнение. Вторая функция завершает работу PVM, запущенной пользователем, но при этом сама задача продолжает выполняться уже как обычная локальная задача и завершает работу обычным образом.

1.6.3 Передача сообщений

Посылка сообщений в PVM предназначена для передачи данных между различными процессам и состоит из трех шагов. Во-первых, буфер данных перед посылкой должен быть проинициализирован с использованием функций pvm_initsend() или pvm_mkbuf(). Во-вторых, пересылаемые данные должны быть "упакованы" в этот буфер. Для упаковки используется некоторе количество комбинаций вызовов функции pvm_pk*(). В FORTRANе упаковка данных производится подпрограмой pvmfpack(). Третий шаг заключается в пересылке данных адресатам. Для этой цели в зависимости от списка адресатов используется вызов функции pvm_send(), в параметрах которой указывается конкретный процесс-приемник, или функции pvm_mcast(), используемой для всенаправленной передачи (то есть всем процессам сразу).

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

для приема любых сообщений

для приема любых сообщений от определенного источника

для приема любых сообщений с определенным message tag

для приема любых сообщений с определенным message tag от определенного источника

Кроме того, существует функция для проверки факта доставки сообщения адресату. Буфер сообщения

call pvmfinitsend( encoding, bufid )

Если пользователь использует только один буфер сообщения (обычно так и делается), то единственная необходимая для работы с буфером функция - это pvm_initsend(). Эта функция вызывается непосредственно перед упаковкой новой порции пересылаемых данных в буфер сообщения. Функция pvm_initsend освобождает буфер и создает новый для упаковки в него данных. Схема кодировки упаковываемых в буфер данных указывается заданием переменной encoding. Возвращаемое в переменную bufid значение является идентификатором буфера. Переменная encoding может принимать следующие значения:

PvmDataDefault - XDR кодировка, используемая в PVM по умолчанию. Эта кодировка используется обычно в гетерогенных кластерах, когда PVM не может знать понимает ли принимающая сторона передаваемый формат данных. Например, когда данные передаются с Linux-машины на Windows-машину. В случае, когда в кластере используется только один тип операционной машины или когда пользователь уверен, что принимающая сторона поймет все правильно, следует использовать тип кодировки PvmDataRaw. PvmDataRaw - без кодировки. Даные передаются без каких либо изменений. Если принимающая сторона не сможет правильно прочитать этот формат, это вызовет возврат кода ошибки в процессе распаковки. PvmDataInPlace - данные остаются на месте, не перемещаясь в буфер посылки. Этот тип кодировки можно использовать для снижения накладных расходов, связанных с перемещением данных в буфер. В этом случае буфер содержит только длины и указатели на передаваемые данные. Когда вызвана pvm_send(), данные копируются непосредственно с того места, где они расположены. Использование этой кодировки накладывает одно ограничение. Передаваемые данные не должны быть изменены между моментом, когда началась их упаковка и моментом окончания передачи буфера сообщения адресату. Однако, при использовании данного типа упаковки, имеется одно заметное преимущество. Функция упаковки pvm_initsend может быть вызвана только один раз в начале прогарммы. Например в начале работы программы мы можем упаковать данные из области перекрытия (см. главу "Декомпозиция данных") и передавать их множество раз по мере необходимости.

1.6.4 Упаковка данных

Для FORTRANа существует только одна функция, которая управялет упаковкой данных всех типов.

call pvmfpack( what, xp, nitem, stride, info )

В пареметре what указывается тип упаковываемых данных. Параметр xp является первым элементом массива данных. Пареметры nitem и stride описаны выше. Параметр info - возвращаемое значение. Значения параметра what представлены в следующей таблице:

STRING          0       REAL4           4

BYTE1           1       COMPLEX8        5

INTEGER2        2       REAL8           6

INTEGER4        3       COMPLEX16       7

Константы, соответствующие значениям параметра what определены в файле pvm3/include/fpvm3.h. Некоторые производители могут расширять этот список дополнительными данными, например INTEGER8, REAL16 и др.

Приведем пример использования всех этих функций:

CALL PVMFINITSEND(PVMRAW, INFO)

CALL PVMFPACK( INTEGER4, NSIZE, 1, 1, INFO )

CALL PVMFPACK( STRING, `row 5 of NXN matrix', 19, 1, INFO )

CALL PVMFPACK( REAL8, A(5,1), NSIZE, NSIZE , INFO )

CALL PVMFSEND( TID, MSGTAG, INFO )

Прием и посылка данных

call pvmfsend( tid, msgtag, info )

call pvmfmcast( ntask, tids, msgtag, info )

Функция pvm_send() помечает сообщение тагом msgtag и выполняет немедленную пересылку данных процессу с соответствющим идентификатором tid.

Функция pvm_mcast() помечает сообщение тагом msgtag и выполняет немедленную пересылку данных все процессам, имеющим идентификаторы, совпадающими со значениями, хранящимися в массиве tids. Длина массива tids равна ntask.

Следующие функции предназначены для совмещения работы по упаковке данных и их пересылке:

call pvmfpsend( tid, msgtag, xp, cnt, type, info )

Эти функции упаковывают массив определенного параметром type типа в буфер и передают его процессу, идентифицированному параметром tid. В FORTRANе типы данных определены так же, как и для процедуры pvmfpack().

Система PVM содержит несколько методов для организации приема сообщений. Причем отсутствует соотыктствие функций. То есть нет такого ограничения, когда сообщение, посланное процедурой pvm_psend должно быть обязательно принято процедурой с именем тип pvm_precv. Вне зависимости от того, как было послано сообщение, принято оно может быть либым из возможных вариантов. То же замечание касается адресной и мультикастной (multicast) передачи.

Следующие процедуры осуществляют блокирующий прием сообщений:

call pvmfrecv( tid, msgtag, bufid )

Эти процедуры инициируют процесс ожидания поступления сообщения, помеченного тагом msgtag от процеса с идентификатором tid (если сообщение еще не пришло). В случае, когда значения параметров tid и/или msgtag равны -1, осуществляется ожидание сообщения от любого процесса и/или сообщения с любым тагом.

После того, как сообщение получено, эти процедуры возвращают управление вызвавшей их программе, передав в bufid идентификатор буфера, в который помещено полученное сообщение. Значение bufid<0 сигнализирует о возникшей ошибке. Аналогом блокирующей функции являются функция

call pvmfnrecv( tid, msgtag, bufid )

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

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

call pvmfprobe( tid, msgtag, bufid )

Если ожидаемое сообщение еще не пришло, эта функция возвращает bufid=0. По пришествии сообщения в bufid возвращается значение отличное от нуля. Функцию можно вызывать неоднократно, заполняя время между вызовами какой-либо другой продуктивной работой. Функция pvm_probe не получает сообщение, для его получение необходимо воспользоваться одной из соответствующих функций.

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

call pvmfprecv( tid, msgtag, xp, cnt, type, rtid, rtag, rcnt, info )

Эту функцию можно использовать для приема сообщений, в которых содержатся однотипные данные. Вызов этой функции инициирует процесс ожидания сообщения, помеченного тагом msgtag от процесса с идентификатором tid. По поступлении сообщения pvm_precv распаковывает данные общим объемом len * (size of data type) в буфер buf.

Страницы: 1, 2, 3, 4, 5, 6, 7


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

© 2010.