Главная страница

Программирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В.. Программирование для многопроцессорных систем в стандарте MPI -. Организация вычислений в многопроцессорных системах


Скачать 1.61 Mb.
НазваниеОрганизация вычислений в многопроцессорных системах
АнкорПрограммирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В..pdf
Дата15.03.2018
Размер1.61 Mb.
Формат файлаpdf
Имя файлаПрограммирование для многопроцессорных систем в стандарте MPI - .pdf
ТипКонтрольные вопросы
#16702
КатегорияИнформатика. Вычислительная техника
страница2 из 26
1   2   3   4   5   6   7   8   9   ...   26
Глава 1. ОРГАНИЗАЦИЯ ВЫЧИСЛЕНИЙ
В МНОГОПРОЦЕССОРНЫХ СИСТЕМАХ
В главе 1 приведен обзор методов организации вычислений в со- временных многопроцессорных системах, получивших в последние годы широкое распространение, рассматривается классификация сис- тем, эффективность параллельных вычислений, техническая реализа- ция многопроцессорных систем и систем передачи данных, методы программирования и, наконец, делается переход к основному объекту настоящего издания – системе программирования в стандарте MPI.
1.1. КЛАССИФИКАЦИЯ МНОГОПРОЦЕССОРНЫХ СИСТЕМ
Наиболее известная классификация параллельных ЭВМ предло- жена Флинном [13] и отражает форму реализуемого ЭВМ паралле- лизма. Основными понятиями классификации являются "поток ко- манд" и "поток данных". Под потоком команд упрощенно понимают последовательность команд одной программы. Поток данных
− это последовательность данных, обрабатываемых одной программой.
Согласно этой классификации имеется четыре больших класса ЭВМ:
1) ОКОД (одиночный поток команд
− одиночный поток данных) или
SISD (Single Instruction
− Single Data). Это последовательные ЭВМ, в которых выполняется единственная программа, т. е. имеется только один счетчик команд.
2) ОКМД (одиночный поток команд
− множественный поток данных) или SIMD (Single Instruction – Multiple Data). В таких ЭВМ выпол- няется единственная программа, но каждая команда обрабатывает массив данных. Это соответствует векторной форме параллелизма.
3) МКОД (множественный поток команд
− одиночный поток данных) или MISD (Multiple Instruction
− Single Data). Подразумевается, что в данном классе несколько команд одновременно работает с одним элементом данных, однако эта позиция классификации Флинна на практике не нашла применения.
4) МКМД (множественный поток команд
− множественный поток данных) или MIMD (Multiple Instruction
− Multiple Data). В таких
ЭВМ одновременно и независимо друг от друга выполняется не- сколько программных ветвей, в определенные промежутки време- ни обменивающихся данными. Такие системы обычно называют

10
многопроцессорными. Далее будут рассматриваться только много- процессорные системы.
Классы многопроцессорных систем. В основе МКМД-ЭВМ ле- жит традиционная последовательная организация программы, расши- ренная добавлением специальных средств для указания независимых фрагментов, которые можно выполнять параллельно. Параллельно- последовательная программа привычна для пользователя и позволяет относительно просто собирать параллельную программу из обычных последовательных программ.
МКМД-ЭВМ имеет две разновидности: ЭВМ с разделяемой (об- щей) и распределенной(индивидуальной) памятью. Структура этих
ЭВМ представлена на рис. 1.1.
а б
Рис. 1.1. Структура ЭВМ с разделяемой (а) и индивидуальной (б) памятью.
Здесь: П – процессор, ИП
− индивидуальная память.
Главное различие между МКМД-ЭВМ с общей и индивидуальной памятью состоит в характере адресной системы. В машинах с разде- ляемой памятью адресное пространство всех процессоров является единым, следовательно, если в программах нескольких процессоров встречается одна и та же переменная Х, то эти процессоры будут об- ращаться в одну и ту же физическую ячейку общей памяти. Это вызы- вает как положительные, так и отрицательные последствия.
Наличие общей памяти не требует физического перемещения дан- ных между взаимодействующими программами, которые параллельно выполняются в разных процессорах. Это упрощает программирование и исключает затраты времени на межпроцессорный обмен.
Однако одновременное обращение нескольких процессоров к об- щим данным может привести к получению неверных результатов.
Рассмотрим следующий пример. Пусть имеется система с разделяе-
П
П
П
Коммутатор
Разделяемая память
П
П
П
ИП
ИП
ИП
Коммутатор

11
мой памятью и двумя процессорами, каждый с одним регистром.
Пусть в первом процессоре выполняется процесс L1, во втором – L2:
L 1: ... X: = X + 1; ...
L 2: ... X: = X + 1; ...
Процессы выполняются асинхронно, используя общую перемен- ную X. При выполнении процессов возможно различное их взаимо- расположение во времени, например, возможны следующие две си- туации:
L1
R1: = X;
R1: = R1 + 1;
X: = R1; ...
(1.1)
L2
R2: = X;
R2: = R2 + 1; X:=
R2;
L1
R1: = X;
R1: = R1 + 1; X: = R1;
(1.2)
L2
R2: = Х; R2:=R2+1;
X: = R2;
Пусть в начальный момент X = V. Тогда в случае (1.1) второй про- цессор производит чтение X до завершения всех операций в первом процессоре, поэтому X = V + 1.
В случае (1.2) второй процессор читает X после завершения всех операций первым процессором, поэтому X = V + 2. Таким образом, ре- зультат зависит от взаиморасположения процессов во времени, что для асинхронных процессов определяется случайным образом. Чтобы исключить такие ситуации, необходимо ввести систему синхрониза- ции параллельных процессов (например, семафоры), что усложняет механизмы операционной системы.
Поскольку при выполнении каждой команды процессорам необхо- димо обращаться в общую память, то требования к пропускной спо- собности коммутатора этой памяти чрезвычайно высоки, что ограни- чивает число процессоров в системах величиной 10...20.
В системах с индивидуальной памятью (с обменом сообщениями) каждый процессор имеет независимое адресное пространство, и нали- чие одной и той же переменной X в программах разных процессоров приводит к обращению в физически разные ячейки памяти. Это вызы- вает физическое перемещение данных между взаимодействующими программами в разных процессорах, однако, поскольку основная часть обращений производится каждым процессором в собственную память, то требования к коммутатору ослабляются, и число процессо- ров в системах с распределенной памятью и коммутатором типа ги- перкуб может достигать нескольких сотен и даже тысяч.

12
1.2. СЕТЕВОЙ ЗАКОН АМДАЛА
Закон Амдала. Одной из главных характеристик параллельных систем является ускорение R параллельной системы, которое опреде- ляется выражением:
n
T
T
R
/
1
=
, где T
1
− время решения задачи на однопроцессорной системе, а T
n
− время решения той же задачи на n
− процессорной системе.
Пусть W = W
ск
+ W
пр
, где W
− общее число операций в задаче,
W
пр
− число операций, которые можно выполнять параллельно, а
W

− число скалярных (нераспараллеливаемых) операций.
Обозначим также через t время выполнения одной операции. То- гда получаем известный закон Амдала [13]:
a
n
n
a
a
t
n
W
W
t
W
R
пр
ск
1 1
1
)
(








+
=

+

=
(1.3)
Здесь a = W
ск
/W
− удельный вес скалярных операций.
Закон Амдала определяет принципиально важные для параллель- ных вычислений положения:
1. Ускорение зависит от потенциального параллелизма задачи (вели- чина 1– а) и параметров аппаратуры (числа процессоров n).
2. Предельное ускорение определяется свойствами задачи.
Пусть, например, a = 0,2 (что является реальным значением), тогда ускорение не может превосходить 5 при любом числе процессоров, то есть максимальное ускорение определяется потенциальным паралле- лизмом задачи. Очевидной является чрезвычайно высокая чувстви- тельность ускорения к изменению величины а.
Сетевой закон Амдала
. Основной вариант закона Амдала не от- ражает потерь времени на межпроцессорный обмен сообщениями.
Эти потери могут не только снизить ускорение вычислений, но и за- медлить вычисления по сравнению с однопроцессорным вариантом.
Поэтому необходима некоторая модернизация выражения (1.3).
Перепишем (1.3) следующим образом:
c
n
a
a
t
W
t
W
n
a
a
t
W
t
n
W
W
t
W
R
c
c
c
c
пр
ск
c
+

+
=


+

+
=

+

+

=
1 1
1 1
)
(
. (1.4)

13
Здесь W
c
−количество передач данных,
t
c
−время одной передачи данных. Выражение
c
n
a
a
c
R
+

+
=
1 1
(1.5) и являетсясетевым законом Амдала. Этот закон определяет следую- щие две особенности многопроцессорных вычислений:
1. Коэффициент сетевой деградации вычислений с:
Т
А
c
c
c
c
t
W
t
W
c

=


=
, (1.6) определяет объем вычислений, приходящийся на одну передачу данных (по затратам времени). При этом с
А
определяет алгорит- мическую составляющую коэффициента деградации, обусловлен- ную свойствами алгоритма, а с
Т
− техническую составляющую, ко- торая зависит от соотношения технического быстродействия про- цессора и аппаратуры сети. Таким образом, для повышения скоро- сти вычислений следует воздействовать на обе составляющие ко- эффициента деградации. Для многих задач и сетей коэффициенты
с
А
и с
Т
могут быть вычислены аналитически и заранее, хотя они определяются множеством факторов: алгоритмом задачи [14,15], размером данных, реализацией функций обмена библиотеки MPI, использованием разделяемой памяти и, конечно, техническими ха- рактеристиками коммуникационных сред и их протоколов.
2. Даже если задача обладает идеальным параллелизмом, сетевое ус- корение определяется величиной
n
c
n
c
n
c
n
R
c


⎯ →



+
=
+
=
0 1
1 1
(1.7) и увеличивается при уменьшении с. Следовательно, сетевой закон
Амдала должен быть основой оптимальной разработки алгоритма и программирования задач, предназначенных для решения на мно- гопроцессорных ЭВМ.
В некоторых случаях используется еще один параметр для изме- рения эффективности вычислений – коэффициент утилизации z:
1 0
1 1


⎯ →



+
=
=
c
n
c
n
R
z
c
. (1.8)

14
Более подробно вопросы эффективности вычислений изложены в главе 12.
1.3. ТЕХНИЧЕСКАЯ РЕАЛИЗАЦИЯ МНОГОПРОЦЕССОРНЫХ СИСТЕМ
Существующие параллельные вычислительные средства класса
MIMD образуют три технических подкласса: симметричные мульти- процессоры (SMP), системы с массовым параллелизмом (МРР) и кла- стеры. В основе этой классификации лежит структурно- функциональный подход.
Симметричные мультипроцессоры
используют принцип разде- ляемой памяти. В этом случае система состоит из нескольких одно- родных процессоров и массива общей памяти (обычно из нескольких независимых блоков). Все процессоры имеют доступ к любой точке памяти с одинаковой скоростью. Процессоры подключены к памяти с помощью общей шины или коммутатора. Аппаратно поддерживается когерентность кэшей.
Наличие общей памяти сильно упрощает взаимодействие процессо- ров между собой, однако накладывает сильные ограничения на их число
− не более 32 в реальных системах. Вся система работает под управлением единой ОС (обычно UNIX-подобной, но для Intel- платформ поддерживается Windows NT).
Системы с массовым параллелизмом
содержат множество про- цессоров (обычно RISC) c индивидуальной памятью в каждом из них
(прямой доступ к памяти других узлов невозможен), коммуникацион- ный процессор или сетевой адаптер, иногда
− жесткие диски и/или другие устройства ввода–вывода. Узлы связаны через некоторую коммуникационную среду (высокоскоростная сеть, коммутатор и т.п.). Общее число процессоров в реальных системах достигает не- скольких тысяч (ASCI Red, Blue Mountain).
Полноценная операционная система может располагаться только на управляющей машине (на других узлах работает сильно урезанный вариант ОС), либо на каждом узле работает полноценная UNIX- подобная ОС (вариант, близкий к кластерному подходу). Программи- рование осуществляется в рамках модели передачи сообщений (биб- лиотеки параллельных функций MPI, PVM, BSPlib).
Кластерные системы
−более дешевый вариантMPP–систем, по- скольку они также используют принцип передачи сообщений, но строятся из компонентов высокой степени готовности [16,2].

15
Вычислительный кластер
− это совокупность компьютеров, объе- диненных в рамках некоторой сети для решения одной задачи. В каче- стве вычислительных узлов обычно используются доступные на рын- ке однопроцессорные компьютеры, двух
− или четырехпроцессорные
SMP-серверы. Каждый узел работает под управлением своей копии операционной системы, в качестве которой чаще всего используются стандартные операционные системы: Linux, NT, Solaris и т.п. Состав и мощность узлов может меняться даже в рамках одного кластера, давая возможность создавать неоднородные системы.
Для кластерных систем в соответствии с сетевым законом Амдала характеристики коммуникационных сетей имеют принципиальное значение.
Коммуникационные сети
[16]имеют две основныехарактери- стики: латентность
− время начальной задержки при посылке сообще- ний и пропускную способность сети, определяющую скорость пере- дачи информации по каналам связи. После вызова пользователем функции посылки сообщения Send() сообщение последовательно про- ходит через целый набор слоев, определяемых особенностями органи- зации программного обеспечения и аппаратуры, прежде чем покинуть процессор. Наличие латентности определяет и тот факт, что макси- мальная скорость передачи по сети не может быть достигнута на со- общениях с небольшой длиной.
Чаще всего используется сеть Fast Ethernet, основное достоинство которой
− низкая стоимость оборудования. Однако большие наклад- ные расходы на передачу сообщений в рамках Fast Ethernet приводят к серьезным ограничениям на спектр задач, которые можно эффективно решать на таком кластере. Если от кластера требуется большая уни- версальность, то нужно переходить на более производительные ком- муникационные сети, например, SCI, Myrinet, некоторые другие. Ха- рактеристики некоторых сетей представлены в приложении 4.
1.4. ПРОГРАММИРОВАНИЕ ДЛЯ СИСТЕМ
С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ
Процессы.
В операционной системе UNIX поддерживается воз- можность параллельного выполнения нескольких пользовательских программ. Каждому такому выполнению соответствует процесс опе- рационной системы [17]. Каждый процесс обладает собственными ре- сурсами, то есть выполняется в собственной виртуальной памяти, и тем самым процессы защищены один от другого, т.е. один процесс не

16
в состоянии неконтролируемым образом прочитать что-либо из памя- ти другого процесса или записать в нее. Однако контролируемые взаимодействия процессов допускаются системой, в том числе за счет возможности разделения одного сегмента памяти между виртуальной памятью нескольких процессов. Каждый процесс может образовать полностью идентичный подчиненный процесс выполнением систем- ного вызова FORK() и дожидаться окончания выполнения своих под- чиненных процессов с помощью системного вызова WAIT.
После создания процесса предок и потомок могут произвольным образом изменять свой контекст. В частности, и предок, и потомок могут выполнить какой-либо из вариантов системного вызова exec, приводящего к полному изменению контекста процесса.
Нити.
Понятие нити (thread, light-weight process
− легковесный процесс, поток управления) давно известно в области операционных систем. В одной виртуальной памяти может выполняться не один по- ток управления. Если несколько процессов совместно пользуются не- которыми ресурсами (общим адресным пространством, общими пере- менными, аппаратными ресурсами и др.), то при доступе к этим ре- сурсам они должны синхронизовать свои действия. Многолетний опыт программирования с использованием явных примитивов син- хронизации показал, что этот стиль "параллельного" программирова- ния порождает серьезные проблемы при написании, отладке и сопро- вождении программ (наиболее трудно обнаруживаемые ошибки в программах обычно связаны с синхронизацией). Это было главной причиной того, что в традиционных вариантах ОС UNIX понятие процесса жестко связывалось с понятием отдельной и недоступной для других процессов виртуальной памяти.
При появлении систем SMP отношение к процессам претерпело существенные изменения. В таких компьютерах физически присутст- вуют несколько процессоров, которые имеют одинаковые по скорости возможности доступа к совместно используемой основной памяти.
Появление подобных машин на мировом рынке поставило проблему их эффективного использования. При применении традиционного подхода ОС UNIX к организации процессов наличие общей памяти не давало эффекта. К моменту появления SMP выяснилось, что техно- логия программирования еще не может предложить эффективного и безопасного способа реального параллельного программирования.
Поэтому пришлось вернуться к явному параллельному программиро-

17
ванию с использованием параллельных процессов в общей виртуаль- ной (а тем самым и основной) памяти с явной синхронизацией.
Нить
− это независимый поток управления с собственным счетчи- ком команд, выполняемый в контексте некоторого процесса. Фактиче- ски, понятие контекста процесса изменяется следующим образом.
Все, что не относится к потоку управления (виртуальная память, деск- рипторы открытых файлов и т.д.), остается в общем контексте процес- са. Вещи, которые характерны для потока управления (регистровый контекст, стеки разного уровня и т.д.), переходят из контекста процес- са в контекст нити. При этом контексты всех нитей остаются вложен- ными в контекст породившего их процесса.
Поскольку нити одного процесса выполняются в общей виртуаль- ной памяти, стек любой нити процесса в принципе не защищен от произвольного (например, по причине ошибки) доступа со стороны других нитей.
Семафоры.
Чтобы исключить упомянутую выше ситуацию, необ- ходимо ввести систему синхронизации параллельных процессов.
Выход заключается в разрешении входить в критическую секцию
(КС) только одному из нескольких асинхронных процессов. Под кри- тической секцией понимается участок процесса, в котором процесс нуждается в ресурсе. Решение проблемы критической секции предло- жил Дейкстра [17] в виде семафоров. Семафоромназывается пере- менная S, связанная, например, с некоторым ресурсом и принимаю- щая два состояния: 0 (запрещено обращение) и 1 (разрешено обраще- ние). Над S определены две операции: V и P. Операция V изменяет значение S семафора на значение S + 1. Действие операции P таково:
1. если S
≠ 0, то P уменьшает значение на единицу;
2. если S = 0, то P не изменяет значения S и не завершается до тех пор, пока некоторый другой процесс не изменит значение S с по- мощью операции V.
Операции V и P считаются неделимыми, т. е. не могут исполняться одновременно.
Приведем пример синхронизации двух процессов, в котором рrocess
1 и process 2 могут выполняться параллельно.
Процесс может захватить ресурс только тогда, когда S:=1. После за- хвата процесс закрывает семафор операции P(S) и открывает его вновь после прохождения критической секции V(S). Таким образом, семафор S обеспечивает неделимость процессов Li и, значит, их по-

18
следовательное выполнение. Это и есть решение задачи взаимного ис- ключения для процессов Li.
begin semaphore S;
S:=1; process 1:
begin
L1:P(S);
Критический участок 1;
V(S);
Остаток цикла, go to L1
end process 2:
begin
L2:P(S);
Критический участок 2;
V(S);
Остаток цикла, go to L2
end
end
OpenMP.
Интерфейс OpenMP [18] является стандартом для про- граммирования на масштабируемых SMP-системах с разделяемой па- мятью. В стандарт OpenMP входят описания набора директив компи- лятора, переменных среды и процедур. За счет идеи "инкрементально- го распараллеливания" OpenMP идеально подходит для разработчи- ков, желающих быстро распараллелить свои вычислительные про- граммы с большими параллельными циклами. Разработчик не создает новую параллельную программу, а просто добавляет в текст последо- вательной программы OpenMP-директивы.
Предполагается, что OpenMP-программа на однопроцессорной платформе может быть использована вкачестве последовательной программы, т.е. нет необходимости поддерживать последовательную и параллельную версии. Директивы OpenMP просто игнорируются последовательным компилятором, а для вызова процедур OpenMP мо- гут быть подставлены заглушки, текст которых приведен в специфи- кациях. В OpenMP любой процесс состоит из нескольких нитей
управления, которые имеют общее адресное пространство, но разные потоки команд и раздельные стеки. В простейшем случае, процесс со- стоит из одной нити.
Обычно для демонстрации параллельных вычислений используют простую программу вычисления числа
π. Рассмотрим, как можно на-

19
писать такую программу в OpenMP. Число
π можно определить сле- дующим образом:
=

+
dx
x
1 0
2 1
1
arctg(1)-arctg(0)=
π/4.
Вычисление интеграла затем заменяют вычислением суммы :


+
=
+
=
1 0
1 2
2 1
4 1
1 4
n
i
i
x
n
dx
x
, где: x
i
= (i-0.5)/n .
В последовательную программу вставлены две строки, и она ста- новится параллельной. program compute_pi parameter (n = 1000) integer i double precision w,x,sum,pi,f,a f(a) = 4.d0/(1.d0+a*a) w = 1.0d0/n sum = 0.0d0;
!$OMP PARALLEL DO PRIVATE(x), SHARED(w)
!$OMP& REDUCTION(+:sum) do i=1,n x = w*(i-0.5d0) sum = sum + f(x) enddo pi = w*sum print *,'pi = ',pi stop end
Программа начинается как единственный процесс на головном процессоре. Он исполняет все операторы вплоть до первой конструк- ции типа PARALLEL. В рассматриваемом примере это оператор
PARALLEL DO, при исполнении которого порождается множество процессов с соответствующим каждому процессу окружением. В рас- сматриваемом примере окружение состоит из локальной (PRIVATE) переменной х, переменной sum редукции (REDUCTION) и одной раз- деляемой (SHARED) переменной w. Переменные х и sum локальны в каждом процессе без разделения между несколькими процессами. Пе- ременная w располагается в головном процессе. Оператор редукции

20
REDUCTION имеет в качестве атрибута операцию, которая применя- ется к локальным копиям параллельных процессов в конце каждого процесса для вычисления значения переменной в головном процессе.
Переменная цикла i является локальной в каждом процессе по своей сути, так как именно с уникальным значением этой переменной поро- ждается каждый процесс. Параллельные процессы завершаются опе- ратором END DO, выступающим как синхронизирующий барьер для порожденных процессов. После завершения всех процессов продол- жается только головной процесс.
Директивы.
Директивы OpenMP с точки зрения Фортрана явля- ются комментариями и начинаются с комбинации символов "!$OMP".
Директивы можно разделить на 3 категории: определение параллель- ной секции, разделение работы, синхронизация. Каждая директива может иметь несколько дополнительных атрибутов
− клауз. Отдельно специфицируются клаузы для назначения классов переменных, кото- рые могут быть атрибутами различных директив.
Директивы порождения нитей
предназначены для генерации и распределения работы между ними, в том числе и для явного распре- деления.
PARALLEL ... END PARALLEL
определяет параллельную областьпрограммы. При входе в эту область порождается (N–1) но- вых процессов, образуется "команда" из N нитей, а порождающая нить получает номер 0 и становится основной нитью команды (т.н. "master thread"). При выходе из параллельной области основная нить дожида- ется завершения остальных нитей и продолжает выполнение в одном экземпляре. Предполагается, что в SMP-системе нити будут распреде- лены по различным процессорам (однако это, как правило, находится в ведении операционной системы).
Директивы разделение работ.
Работа распределяется директи- вами
DO
,
SECTIONS
и
SINGLE
. Возможно также явное управление распределением работы с помощью функций, возвращающих номер текущей нити и общее число нитей. По умолчанию код внутри
PARALLEL
исполняется всеми нитями одинаково. Директива
DO ...
[ENDDO]
определяет параллельный цикл. Директива
SECTIONS ...
END SECTIONS
определяет набор независимых секций кода. Секции отделяются друг от друга директивой
SECTION
. Директива
SINGLE
... END SINGLE
определяет блок кода, который будет исполнен толь- ко одной нитью (первой, которая дойдет до этого блока).

21
Директивы синхронизации.
Директива
MASTER ... END
MASTER
определяет блок кода, который будет выполнен только master-ом (нулевой нитью). Директива
CRITICAL ... END
CRITICAL
определяет критическую секцию, то есть блок кода, ко- торый не должен выполняться одновременно двумя или более нитями.
Директива
BARRIER
определяет точку барьерной синхронизации, в которой каждая нить дожидается всех остальных. Существуют и дру- гие директивы синхронизации.
Классы переменных.
OpenMP–переменные в параллельных об- ластях программы разделяются на два основных класса:
SHARED
(общие
− под именем A все нити видят одну переменную) и
PRIVATE
(приватные
− под именем A каждая нить видит свою пере- менную).
1.5. ПРОГРАММИРОВАНИЕ ДЛЯ СИСТЕМ
С ПЕРЕДАЧЕЙ СООБЩЕНИЙ
Система программирования
MPI
относится к классу МКМД ЭВМ с индивидуальной памятью, то есть к многопроцессорным системам с обменом сообщениями. MPI имеет следующие особенности:
• MPI − библиотека, а не язык. Она определяет имена, вызовы проце- дур и результаты их работы. Программы, которые пишутся на
FORTRAN, C, и C++ компилируются обычными компиляторами и связаны с MPI–библиотекой.
• MPI − описание, а не реализация. Все поставщики параллельных компьютерных систем предлагают реализации MPI для своих ма- шин как бесплатные, и они могут быть получены из Интернета.
Правильная MPI-программа должна выполняться на всех реализа- циях без изменения.
• MPI соответствует модели многопроцессорной ЭВМ с передачей сообщений.
В модели передачи сообщений процессы, выполняющиеся парал- лельно, имеют раздельные адресные пространства. Связь происходит, когда часть адресного пространства одного процесса скопирована в адресное пространство другого процесса. Эта операция совместная и возможна только когда первый процесс выполняет операцию переда- чи сообщения, а второй процесс
− операцию его получения.
Процессы в MPI принадлежат группам. Если группа содержит
n
процессов, то процессы нумеруются внутри группы номерами, кото-

22
рые являются целыми числами от 0 до
n-l
. Имеется начальная группа, которой принадлежат все процессы в реализации MPI.
Понятия контекста и группы объединены в едином объекте, назы- ваемом коммуникатором. Таким образом, отправитель или получа- тель, определенные в операции посылки или получения, всегда обра- щается к номеру процесса в группе, идентифицированной данным коммуникатором.
В МPI базисной операцией посылки является операция:
MPI_Send (address, count, datatype, destination, tag, comm), где (
address, count, datatype
)
− количество (
count)
объектов типа
datatype
, начинающихся с адреса
address
в буфере посылки;
destination
– номер получателя в группе, определяемой коммуника- тором
comm
;
tag
− целое число, используемое для описания сообще- ния;
comm
– идентификатор группы процессов и коммуникационный контекст.
Базисной операцией приема является операция:
MPI_Recv (address, maxcount, datatype, source, tag, comm, status), где (
address, count, datatype
) описывают буфер приемника, как в случае
MPI_Send
;
sourse
– номер процесса-отправителя сообщения в группе, определяемой коммуникатором
comm
;
status
– содержит ин- формацию относительно фактического размера сообщения, источника и тэга.
Sourse, tag, count
фактически полученного сообщения восста- навливаются на основе
status
В MPI используются коллективные операции, которые можно раз- делить на два вида:
• операции перемещения данных между процессами. Самый простой из них – широковещание (broadcasting), MPI имеет много и более сложных коллективных операций передачи и сбора сообщений;
• операции коллективного вычисления (минимум, максимум, сумма и другие, в том числе и определяемые пользователем операции).
В обоих случаях библиотеки функций коллективных операций строятся с использованием знания о преимуществах структуры ма- шины, чтобы увеличить параллелизм выполнения этих операций.
Часто предпочтительно описывать процессы в проблемно- ориентированной топологии. В MPI используется описание процессов в топологии графовых структур и решеток.

23
В MPI введены средства, позволяющие определять состояние про- цесса вычислений, которые позволяют отлаживать программы и улучшать их характеристики.
В MPI имеются как блокирующие операции
send
и
receive
, так и неблокирующий их вариант, благодаря чему окончание этих операций может быть определено явно. MPI также имеет несколько коммуника- ционных режимов. Стандартный режим соответствует общей практи- ке в системах передачи сообщений. Синхронный режим требует бло- кировать
send
на время приема сообщения в противоположность стандартному режиму, при котором
send
блокируется до момента за- хвата буфера. Режим по готовности (для
send
) – способ, предостав- ленный программисту, чтобы сообщить системе, что этот прием был зафиксирован, следовательно, низлежащая система может использо- вать более быстрый протокол, если он доступен. Буферизованный ре- жим позволяет пользователю управлять буферизацией.
Программы MPI могут выполняться на сетях машин, которые имеют различные длины и форматы для одного и того же типа
datatype
, так что каждая коммуникационная операция определяет структуру и все компоненты
datatype
. Следовательно, реализация всегда имеет достаточную информацию, чтобы делать преобразования формата данных, если они необходимы. MPI не определяет, как эти преобразования должны выполняться, разрешая реализации произво- дить оптимизацию для конкретных условий.
Процесс
есть программная единица, у которой имеется собствен- ное адресное пространство и одна или несколько нитей.
Процессор
− фрагмент аппаратных средств, способный к выполнению программы.
Некоторые реализации MPI устанавливают, что в программе MPI все- гда одному процессу соответствует один процессор; другие
− позво- ляют размещать много процессов на каждом процессоре.
Если в кластере используются SMP–узлы (симметричная много- процессорная система с множественными процессорами), то для орга- низации вычислений возможны два варианта.
1. Для каждого процессора в SMP-узле порождается отдельный MPI- процесс. MPI-процессы внутри этого узла обмениваются сообще- ниями через разделяемую память (необходимо настроить MPICH соответствующим образом).
2. На каждой узле запускается только один MPI-процесс. Внутри ка- ждого MPI-процесса производится распараллеливание в модели "общей памяти", например с помощью директив OpenMP.

24
Чем больше функций содержит библиотека MPI, тем больше воз- можностей представляется пользователю для написания эффективных программ. Однако для написания подавляющего числа программ принципиально достаточно следующих шести функций:
MPI_Init
Инициализация MPI
MPI_Comm_size
Определение числа процессов
MPI_Comm_rank
Определение процессом собственного номера
MPI_Send
Посылка сообщения
MPI_Recv
Получение сообщения
MPI_Finalize Завершение программы MPI
В качестве примера параллельной программы, написанной в стан- дарте MPI для языка С, рассмотрим программу вычисления числа
π.
Алгоритм вычисления
π уже описывался в параграфе 1.4.
#include "mpi.h"
#include int main ( int argc, char *argv[ ] )
{ int n, myid, numprocs, i; double mypi, pi, h, sum, x, t1, t2, PI25DT = 3.141592653589793238462643;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid); while (1)
{ if (myid == 0)
{ printf ("Enter the number of intervals: (0 quits) "); scanf ("%d", &n); t1 = MPI_Wtime();
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); if (n == 0) break; else
{ h = 1.0/ (double) n; sum = 0.0; for (i = myid +1; i <= n; i+= numprocs)
{ x = h * ( (double)i - 0.5); sum += (4.0 / (1.0 + x*x));
} mypi = h * sum;
MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0,
MPI_COMM_WORLD); if (myid == 0)
{ t2 = MPI_Wtime();

25
printf ("pi is approximately %.16f. Error is %.16f\n",pi, fabs(pi - PI25DT)); printf ("'time is %f seconds \n", t2-t1);
}
}
}
MPI_Finalize(); return 0;
}
В программе после нескольких строк определения переменных следуют три строки, которые есть в каждой MPI–программе:
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
Обращение к
MPI_Init
должно быть первым обращением в MPI–
программе, оно устанавливает "среду" MPI. В каждом выполнении программы может выполняться только один вызов
MPI_Init
Коммуникатор
MPI_COMM_WORLD
описывает состав процес- сов и связи между ними. Вызов
MPI_Comm_size
возвращает в
numprocs
число процессов, которые пользователь запустил в этой программе. Значение
numprocs
− размер группы процессов, связан- ной с коммуникатором
MPI_COMM_WORLD
. Процессы в любой группе нумеруются последовательными целыми числами, начиная с 0.
Вызывая
MPI_ Comm_rank,
каждый процесс выясняет свой номер
(
rank)
в группе, связанной с коммуникатором. Затем главный процесс
(который имеет
myid
=0) получает от пользователя значение числа прямоугольников
n
:
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
Первые три параметра соответственно обозначают адрес, количе- ство и тип данных. Четвертый параметр указывает номер источника данных (головной процесс), пятый параметр – название коммуникато- ра группы. Таким образом, после обращения к
MPI_Bcast
все процес- сы имеют значение
n
и собственные идентификаторы, что является достаточным для каждого процесса, чтобы вычислить
mypi
− свой вклад в вычисление
π. Для этого каждый процесс вычисляет область каждого прямоугольника, начинающегося с
myid + l
Затем все значения
mypi
, вычисленные индивидуальными процес- сами, суммируются с помощью вызова
Reduce
:

26
MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0,
MPI_COMM_WORLD);
Первые два параметра описывают источник и адрес результата.
Третий и четвертый параметр описывают число данных (1) и их тип, пятый параметр – тип арифметико-логической операции, шестой – номер процесса для размещения результата.
Затем по метке 10 управление передается на начало цикла. Этим пользователю предоставляется возможность задать новое
n
и повы- сить точность вычислений. Когда пользователь печатает нуль в ответ на запрос о новом
n
, цикл завершается, и все процессы выполняют:
MPI_Finalize();
после которого любые операции MPI выполняться не будут.
Функция MPI_Wtime() используется для измерения времени ис- полнения участка программы, расположенного между двумя включе- ниями в программу этой функции.
Ранее говорилось, что для написания большинства программ дос- таточно 6 функции, среди которых основными являются функции об- мена сообщениями типа “точка-точка” (в дальнейшем – функции пар- ного обмена). Программу вычисления можно написать с помощью функций парного обмена, но функции, относящиеся к классу коллек- тивных обменов, как правило, будут эффективнее. Коллективные функции
Bcast
и
Reduce
можно выразить через парные операции
Send
и
Recv
. Например, для той же программы вычисления числа π операция
Bcast
для рассылки числа интервалов выражается через цикл следующим образом: for (i=0; i MPI_Send(&n, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
Параллельная MPI программа может содержать различные испол- няемые файлы. Этот стиль параллельного программирования часто называется MPMD (множество программ при множестве данных) в отличие от программ SPMD (одна программа при множестве данных).
SPMD не следует путать с SIMD (один поток команд при множестве данных). Вышеприведенная программа вычисления числа π относится к классу программ SPMD. Такие программы значительно легче писать и отлаживать, чем программы MPMD. В общем случае системы SPM и MPI могут имитировать друг друга:

27 1. Посредством организации единого адресного пространства для физически разделенной по разным процессорам памяти.
2. На SMP–машинах вырожденным каналом связи для передачи со- общений служит разделяемая память.
3. Путем использования компьютеров с разделяемой виртуальной памятью. Общая память как таковая отсутствует. Каждый процес- сор имеет собственную локальную память и может обращаться к локальной памяти других процессоров, используя "глобальный ад- рес". Если "глобальный адрес" указывает не на локальную память, то доступ к памяти реализуется с помощью сообщений, пересы- лаемых по коммуникационной сети.
КОНТРОЛЬНЫЕ ВОПРОСЫ И ЗАДАНИЯ К ГЛАВЕ 1
Контрольные вопросы к 1.1
1. Какие понятия положены в основу классификации Флинна?
2. Назовите и опишите классы параллельных ЭВМ по Флинну.
3. Что такое многопроцессорные ЭВМ с разделяемой памятью?
4. Что вызывает некорректность вычислений в ЭВМ с разделяемой памятью?
5. Каковы достоинства и недостатки ЭВМ с передачей сообщений?
Контрольные вопросы к 1.2
1. Что такое ускорение вычислений?
2. Что определяет закон Амдала?
3. Какую характеристику определяет сетевой закон Амдала?
4. Какие факторы влияют на эффективность сетевых вычислений?
Контрольные вопросы к 1.3
1. Определите три класса технической реализации многопроцессорных ЭВМ.
2. Что такое симметричные мультипроцессоры (SMP)?
3. Каковы особенности систем с массовым параллелизмом (MPP)?
4. Дайте определение вычислительного кластера.
5. Опишите виды кластеров, их особенности, дайте примеры кластеров.
6. Что такое коммуникационная сеть, каковы ее основные параметры?
Контрольные вопросы к 1.4
1. Определите понятие процесса и нити, в чем их различие?
2. Как в Unix создаются процессы, нити?
3. Что такое семафоры, для чего они необходимы?
4. Что такое стандарт OpenMP?
5. Опишите как выполняется в языке OpenMP программа вычисления числа π.
6. Назовите типы директив стандарта OpenMP.
7. Какие классы переменных используются в OpenMP?

28
Контрольные вопросы к 1.5
1. Что такое стандарт MPI?
2. Назовите основные операции передачи и приема в MPI.
3. Назовите и опишите состав и назначение параметров обменных функций MPI.
4. Что такое процесс и процессор в MPI?
5. Перечислите минимально возможный состав MPI функций.
6. Расскажите, как выполняется программа MPI для вычисления числа π.
7. Какой коммуникатор определен после выполнения функции MPI_Init?
8. Можно ли использовать функции MPI до вызова MPI_Init?
9. Как в MPI определить номер процесса?
10. Как узнать число запущенных процессов приложения?
11. Возможна ли замена в MPI коллективных операций на парные обмены?
1   2   3   4   5   6   7   8   9   ...   26


написать администратору сайта