
Structured Computer Organization (Архитектура компьютера) / computer_organization_2003
.pdf
Мультикомпьютеры с передачей сообщений |
633 |
она сделает вызов позднее, когда у нее будет время. В результате отправитель вообще не блокируется. Недостаток этого метода состоит в том, что когда отправитель продолжает работу после совершения операции send, он не может снова использовать буфер сообщений, так как есть вероятность, что сообщение еще не отправлено. Отправитель каким-то образом должен определять, когда он может снова использовать буфер. Например, можно опрашивать систему или совершать прерывание, когда буфер имеется в наличии. В обоих случаях программное обеспечение очень сложное.
В следующих двух разделах мы рассмотрим две популярные системы с передачей сообщений, которые применяются во многих мультикомпьютерах: PVM и MPI. Существуют и другие системы, но эти две наиболее распространенные.
PVM — виртуальная машина параллельного действия
PVM (Parallel Virtual Machine — виртуальная машина параллельного действия) —
это система с передачей сообщений, изначально разработанная для машин COW с операционной системой UNIX [45, 142]. Позднее она стала применяться в других машинах, в том числе в системах МРР. Это самодостаточная система с управлением процессами и системой ввода-вывода.
PVM состоит из двух частей: библиотеки, вызываемой пользователем, и «сторожевого» процесса, который работает постоянно на каждой машине в мультикомпьютере. Когда PVM начинает работу, она определяет, какие машины должны быть частью ее виртуального мультикомпьютера. Для этого она читает конфигурационный файл. «Сторожевой» процесс запускается на каждой из этих машин. Машины можно добавлять и убирать, вводя команды на консоли PVM.
Можно запустить п параллельных процессов с помощью команды spawn -count n prog
Каждый процесс запустит prog. PVM решает, куда поместить процессы, но пользователь может сам подменять их с помощью аргументов команды spawn. Процессы могут запускаться из работающего процесса — для этого нужно вызвать процедуру Pvm_spawn. Процессы могут быть организованы в группы, причем состав групп может меняться во время выполнения программы.
Взаимодействие в машине PVM осуществляется с помощью примитивов для передачи сообщений таким образом, чтобы взаимодействовать могли машины с разными системами счисления. Каждый процесс PVM в каждый момент времени имеет один активный пересылочный буфер и один активный приемный буфер. Отправляя сообщение, процесс вызывает библиотечные процедуры, запаковывающие значения с самоописанием в активный пересылочный буфер, чтобы получатель мог узнать их и преобразовать в исходный формат.
Когда сообщение скомпоновано, отправитель вызывает библиотечную процедуру pvm_send, которая представляет собой блокирующий сигнал send. Получатель может поступить по-разному. Во-первых, он может вызвать процедуру pvm_recv, которая блокирует получателя до тех пор, пока не придет подходящее сообщение. Когда вызов возвратится, сообщение будет в активном приемном буфере. Оно может быть распаковано и преобразовано в подходящий для данной машины формат с помощью набора распаковывающих процедур. Во-вторых, получатель может вызвать процедуру pvmjtrecv, которая блокирует получателя на

6 3 4 Глава 8. Архитектуры компьютеров параллельного действия
определенный промежуток времени, и если подходящего сообщения за это время не пришло, он разблокируется. Процедура нужна для того, чтобы не заблокировать процесс навсегда. Третий вариант — процедура pvmjirecv, которая сразу же возвращает значение — это может быть либо сообщение, либо указание на отсутствие сообщений. Вызов можно повторять, чтобы опрашивать входящие сообщения.
Помимо всех этих примитивов PVM поддерживает широковещание (процедураpvm_bcast) и мультивещание (процедураpvm_mcasi). Первая процедура отправляет сообщение всем процессам в группе, вторая посылает сообщение только некоторым процессам, входящим в определенный список.
Синхронизация между процессами осуществляется с помощью процедуры pvmjbarrier. Когда процесс вызывает эту процедуру, он блокируется до тех пор, пока определенное число других процессов не достигнет барьера и они не вызовут эту же процедуру. Существуют другие процедуры для управления главной вычислительной машиной, группами, буферами, для передачи сигналов, проверки состояния и т. д. PVM — это простой, легкий в применении пакет, имеющийся в наличии в большинстве компьютеров параллельного действия, что и объясняет его популярность.
MPI — интерфейс с передачей сообщений
Следующий пакет для программирования мультикомпьютеров — MPI (MessagePassing Interface — интерфейс с передачей сообщений). MPI гораздо сложнее, чем PVM. Он содержит намного больше библиотечных вызовов и намного больше параметров накаждый вызов. Первая версия MPI, которая сейчас называется MPI-1, была дополнена второй версией, MPI-2, в 1997 году. Ниже мы в двух словах расскажем о MPI-1, а затем посмотрим, что нового появилось в MPI-2. Более подробную информацию об MPI см. в книгах [52, 134].
MPI-1, в отличие от PVM, никак не связана с созданием процессов и управлением процессами. Создавать процессы должен сам пользователь с помощью локальных системных вызовов. После создания процессы организуются в группы, которые уже не изменяются. Именно с этими группами и работает MPI.
В основе MPI лежат 4 понятия: коммуникаторы, типы передаваемых данных, операции коммуникации и виртуальные топологии. Коммуникатор — это группа процессов плюс контекст. Контекст — это метка, которая идентифицируетчто-либо (например, фазу выполнения). В процессе отправки и получения сообщений контекст может использоваться для того, чтобы несвязанные сообщения не мешали друг другу.
Сообщения могут быть разныхтипов: символьные, целочисленные (short, regular и long integers), с обычной и удвоенной точностью, с плавающей точкой и т. д. Можно образовать новые типы сообщений из уже существующих.
MPI поддерживает множество операций коммуникации. Ниже приведена операция, которая используется для отправки сообщений:
MPI_Send(buffer. count. data_type. destination, tag. communicator)
Этот вызов отправляет содержимое буфера (buffer) с элементами определенного типа (datatype) в пункт назначения. Count — это число элементов буфера. Поле tag помечает сообщение; получатель может сказать, что он будет принимать

Мультикомпьютеры с передачей сообщений |
635 |
сообщение только с данным тегом. Последнее поле показывает, к какой группе процессов относится целевой процесс (поле destination — это просто индекс списка процессов из определенной группы). Соответствующий вызов для получения сообщения таков:
MPI_Recv(&buffer, count, datajtype, source, tag. communicator, Sstatus)
В нем сообщается, что получатель ищет сообщение определенного типа из определенного источника с определенным тегом.
MPI поддерживает 4 основных типа коммуникации. Первый тип синхронный. В нем отправитель не может начать передачу данных, пока получатель не вызовет процедуру MPI_Recv. Второй тип — коммуникация с использованием буфера. Ограничение для первого типа здесь недействительно. Третий тип стандартный. Он зависит от реализации и может быть либо синхронным, либо с буфером. Четвертый тип сходен с первым. Здесь отправитель требует, чтобы получатель был доступен, но без проверки. Каждый из этих примитивов бывает двух видов: блокирующим и неблокирующим, что в сумме дает 8 примитивов. Получение может быть только в двух вариантах: блокирующим и неблокирующим.
MPI поддерживает коллективную коммуникацию — широковещание, распределение и сбор данных, обмен данными, агрегацию и барьер. При любых формах коллективной коммуникации все процессы в группе должны делать вызов, причем с совместимыми параметрами. Если этого сделать не удается, возникает ошибка. Например, процессы могут быть организованы в виде дерева, в котором значения передаются от листьев к корню, подчиняясь определенной обработке на каждом шаге (это может быть сложение значений или взятие максимума). Это типичная форма коллективной коммуникации.
Четвертое основное понятие в MPI — виртуальная топология, когда процессы могут быть организованы в дерево, кольцо, решетку, тор и т. д. Такая организация процессов обеспечивает способ наименования каналов связи и облегчает коммуникацию.
В MPI-2 были добавлены динамические процессы, доступ к удаленной памяти, неблокирующая коллективная коммуникация, расширяемая поддержка процессов ввода-вывода, обработка в режиме реального времени и многие другие особенности. В научном сообществе идет война между лагерями MPI и PVM. Те, кто поддерживают PVM, утверждают, что эту систему проще изучать и легче использовать. Те, кто на стороне MPI, утверждают, что эта система выполняет больше функций и, кроме того, она стандартизована, что подтверждается официальным документом.
Совместно используемая память на прикладном уровне
Из наших примеров видно, что мультикомпьютеры можно расширить до гораздо больших размеров, чем мультипроцессоры. Sun Enterprise 10000, где максимальное число процессоров — 64, и NUMA-Q, где максимальное число процессоров — 256, являются представителями больших мультипроцессоров UMA и NUMA соответственно. А машины ТЗЕ и Option Red содержат 2048 и 9416 процессоров соответственно.

6 3 6 Глава 8. Архитектуры компьютеров параллельного действия
Однако мультикомпьютеры не имеют совместно используемой памяти на архитектурном уровне. Это и привело к появлению таких систем с передачей сообщений, как PVM и MPI. Большинство программистов предпочитают иллюзию совместно используемой памяти, даже если ее на самом деле не существует. Если удастся достичь этой цели, мы сразу получим дешевое аппаратное обеспечение больших размеров плюс обеспечим легкость программирования.
Многие исследователи пришли к выводу, что общая память на архитектурном уровне может быть нерасширяемой, но зато существуют другие способы достижения той же цели. Из рисунка 8.3 видно, что есть и другие уровни, на которых можно ввести совместно используемую память. В следующих разделах мы рассмотрим, как в мультикомпьютере можно ввести совместно используемую память в модель программирования при отсутствии ее на уровне аппаратного обеспечения.
Распределенная совместно используемая память
Один из классов систем с общей памятью на прикладном уровне — это системы со страничной организацией памяти. Такая система называется DSM (Distributed
Shared Memory — распределенная совместно используемая память). Идея проста:
ряд процессоров в мультикомпьютере разделяет общее виртуальное адресное пространство со страничной организацией. Самый простой вариант — когда каждая страница содержится в ОЗУ ровно для одного процессора. На рис. 8.34, а мы видим общее виртуальное адресное пространство, которое состоит из 16 страниц и распространяется на 4 процессора.
Когда процессор обращается к странице в своем локальном ОЗУ, чтение и запись происходят без задержки. Однако если процессор обращается к странице из другого ОЗУ, происходит ошибка из-за отсутствия страницы. Только в этом случае отсутствующая страница берется не с диска. Вместо этого операционная система посылает сообщение в узел, в котором находится данная страница, чтобы преобразовать ее и отправить к процессору. После получения страницы она преобразуется в исходное состояние, а приостановленная команда выполняется заново, как и при обычной ошибке из-за отсутствия страницы. На рис. 8.34, б мы видим ситуацию после того, как процессор 0 получил ошибку из-за отсутствия страницы 10, которая была передана из процессора 1 в процессор 0.
Впервые идея была реализована в машине IVY [83, 84]. В результате в мультикомпьютере появилась память совместного использования, согласованная по последовательности. В целях улучшения производительности возможны оптимизации. Первая оптимизация, появившаяся в IVY, — страницы, предназначенные только для чтения, могли присутствовать в нескольких узлах одновременно. В случае ошибки из-за отсутствия страницы в запрашивающую машину посылается копия этой страницы, но оригинал остается на месте, поскольку нет никакой опасности конфликтов. На рисунке 8.34, в показана ситуация, когда два процессора делят общую страницу, предназначенную только для чтения (это страница 10).
Но даже при такой оптимизации трудно достичь высокой производительности, особенно когда один процесс записывает несколько слов вверху какой-либо страницы, а другой процесс в другом процессоре в это же время записывает несколько слов внизу той же страницы. Поскольку существует только одна копия этой стра-

Мультикомпьютеры с передачей сообщений |
637 |
ницы, страница постоянно должна передаваться туда и обратно. Эта ситуация называетсяложнымсовместнымиспользованием.
Глобальнаявиртуальнаяпамятьсовместногоиспользования,состоящаяиз16страниц
-Память
|
|
|
|
|
Сеть |
0 |
2 5 |
1 |
3 6 |
4 | 7 | 11 |
рГаГ] 15 |
9 |
10 |
8 |
|
12 |
|
Процессор 0 |
Процессор 1 |
Процессор 2 |
Процессор 3 |
Рис.8.34.Виртуальноеадресноепространство,состоящееиз16страниц,которые распределенымеждучетырьмяузламивмультикомпьютере:исходноеположение(а); положение после обращения процессора0 кстранице 10 (б); положение после обращения процессора 0 к странице 10 (в); в данном случае эта страница предназначена только для чтения
Проблему ложного совместного использования можно разрешить по-разному. Например, можно отказаться от согласованности по последовательности в пользу свободной согласованности [6]. Потенциально записываемые страницы могут присутствовать в нескольких узлах одновременно, но перед записью процесс должен совершить операцию acquire, чтобы сообщить о своем намерении. В этот момент все копии, кроме последней, объявляются недействительными. Нельзя делать



6 4 0 Глава 8. Архитектуры компьютеров параллельного действия
При каждом прохождении цикла одна из задач выдается в пространство кортежей. Каждый рабочий процесс начинает работу с получения кортежа с описанием задачи, используя операцию
in("Task-bag". ?job):
Затем он выполняет эту задачу. По выполнении задачи он получает следующую. Новая задача тоже может быть помещена в пакет задач во время выполнения. Таким образом, работа динамически распределяется среди рабочих процессов, и каждый рабочий процесс занят постоянно.
Существуют различные реализации Linda в мультикомпьютерных системах. Во всех реализациях ключевым является вопрос о том, как распределить кортежи по машинам и как их находить. Возможные варианты — широковещание и каталоги. Дублирование — это тоже важный вопрос. Подробнее об этом см. [16].
Огса
Несколько другой подход к совместно используемой памяти на прикладном уровне в мультикомпьютере — в качестве общейсовместно используемойединицы использовать полные объекты, а не просто кортежи. Объекты состоят из внутреннего (скрытого) состояния и процедур для оперирования этим состоянием. Поскольку программист не имеет прямого доступа к состоянию, появляется возможность совместного использования ресурсов машинами, которые не имеют общей физической памяти.
Одна из таких систем называется Огса [11, 13, 14]. Огса — это традиционный язык программирования (основанный на Modula 2), к которому добавлены две особенности — объекты и возможность создавать новые процессы. Объект Огса — это стандартный тип данных, аналогичный объекту в языкеJava или пакету в языке Ada. Объект заключает в себе внутренние структуры данных и написанные пользователем процедуры, которые называются операциями. Объекты пассивны, то есть они не содержат потоков, которым можно посылать сообщения. Процессы получают доступ к внутренним данным объекта путем вызова его процедур.
Каждая процедура в Огса состоит из списка пар (предохранитель (guard), блок операторов). Предохранитель — это логическое выражение, которое может принимать значение «истина» (true) или «ложь (false). Когда вызывается операция, все ее предохранители оцениваются в произвольном порядке. Если все они ложны (false), вызывающий процесс приостанавливается до тех пор, пока один из них не примет значение true. При нахождении предохранителя со значением true выполняется следующий за ним блок выражений. В листинге 8.5 показан объект stack с двумя операциями push и pop.
Листинг 8.5. Упрощенный объект stack в системе Огса с внутренними данными и двумя операциями
Object implementation stack; |
|
|
top:integer; |
#хранилище для |
стека |
stack:array[integer O..N-l]of integer; |
|
|
operation pushOtem:integer); |
#функция. которая ничего не |
|
begin |
#возвращает |
|
stack[top]:=item; |
#помещаем элемент в |
стек |
top:=top+l: |
#увеличения указателя стека |
|
end: |
|
|

|
Мультикомпьютеры с передачей сообщений |
641 |
operation popО integer. |
#функция, которая возвращает |
|
begin |
#целое число |
|
guard top>0 do |
Приостанавливает работу, если стек пуст |
|
top =top-l. |
#уменьшает указатель стека |
|
return stack[top]: |
# возвращает вершину стека |
|
od. |
|
|
end |
|
|
begin |
|
|
top =0, |
Инициализация |
|
end |
|
|
Как только определен объект stack, нужно объявить переменные этого типа: s, t stack.
Такая запись создает два стековых объекта и устанавливает переменную top в каждом объекте на 0. Целочисленную переменную к можно поместить в стек s с помощью выражения
s$push(k)
и т. д. Операция pop содержит предохранитель, поэтому попытка вытолкнуть переменную из пустого стека вызовет блокировку вызывающего процесса до тех пор, пока другой процесс не положит что-либо в стек.
Осга содержит оператор ветвления (fork statement) для создания нового процесса в процессоре, определяемом пользователем. Новый процесс запускает процедуру, названную в команде ветвления. Параметры, в том числе объект, могут передаваться новомупроцессу. Именно так объекты распределяются среди машин. Например, выражение
for I in I n do fork foobar(s) on I; od;
порождает новый процесс на каждой из машин с 1 по п, запуская программу foobar в каждой из них. Поскольку эти п новых процессов (а также исходный процесс) работают параллельно, они все могут помещать элементы в общий стек s и выталкивать элементы из общего стека s, как будто все они работают на мультипроцессоре с памятью совместного использования.
Операции в объектах совместного использования атомарны и согласованы по последовательности. Если несколько процессов выполняют операции над одним общим объектом практически одновременно, система выбирает определенный порядок выполнения, и все процессы «видят» этот же порядок.
В системе Осга данные совместного использования совмещаются с синхронизацией не так, как в системах со страничной организацией памяти. В программах с параллельной обработкой нужныдва вида синхронизации. Первый вид — взаимное исключение. Этот метод не позволяет двум процессам одновременно выполнять одну и ту же критическую область. В системе Огса каждая операция над общим объектом похожа на критическую область, поскольку система гарантирует, что конечный результат будет таким же, как если бы все критические области выполнялись последовательно одна за другой. В этом отношении объект Огса похож на распределенное контролирующее устройство [61].
Второй вид синхронизации — условная синхронизация, при которой процесс блокируется и ждет выполнения определенного условия. В системе Огса условная синхронизация осуществляется при помощи предохранителей. В примере, приве-

6 4 2 Глава 8. Архитектуры компьютеров параллельного действия
денном в листинге 8.5, процесс, который пытается вытолкнуть элемент из пустого стека, блокируется до появления в стеке элементов.
В системе Огса допускается копирование объектов, миграция и вызов операций. Каждый объект может находиться в одном из двух состояний: он может быть единственным, а может быть продублирован. В первом случае объект существует только на одной машине, поэтому все запросы отправляются туда. Продублированный объект присутствует на всех машинах, которые содержат процесс, использующий этот объект. Это упрощает операцию чтения (поскольку ее можно производить локально), но усложняет процесс обновления. При выполнении операции, которая изменяет продублированный объект, сначала нужно получить от центрального процесса порядковый номер. Затем в каждую машину, содержащую копию объекта, отправляется сообщение о необходимости выполнить эту операцию. Поскольку все такие обновления обладают порядковыми номерами, все машины просто выполняют операции в порядке номеров, что гарантирует согласованность по последовательности.
Globe
Большинство систем DSM, Linda и Огса работают в пределах одного здания или предприятия. Однако можно построить систему с совместно используемой памятью на прикладном уровне, которая может распространяться на весь мир. В системе Globe объект может находиться в адресном пространстве нескольких процессов одновременно, возможно, даже на разных континентах [72,154]. Чтобы получить доступ к данным общего объекта, пользовательские процессы должны пройти через его процедуры, поэтому для разных объектов возможны разные способы реализации. Например, можно иметь один экземпляр данных, который запрашивается по мере необходимости (это удобно для данных, часто обновляемых одним владельцем). Другой вариант — когда все данные находятся в каждой копии объекта, а сигналы об обновлении посылаются каждой копии в соответствии с надежным протоколом широковещания.
Цель системы Globe — работать на миллиард пользователей и содержать триллион объектов — делает эту систему амбициозной. Ключевыми моментами являются размещение объектов, управление ими, а также расширение системы. Система Globe содержит общую сеть, в которой каждый объект может иметь собственную стратегию дублирования, стратегию защиты и т. д.
Среди других широкомасштабных систем можно назвать Globus [40,41] и Legion [50,51], но они, в отличие от Globe, не создают иллюзию совместного использованияпамяти.
Краткое содержание главы
Компьютеры параллельной обработки можно разделить на две основные категории: SIMD и MIMD. Машины SIMD выполняют одну команду одновременно над несколькими наборами данных. Это массивно-параллельные процессоры и векторные компьютеры. Машины MIMD выполняют разные программы на разных машинах. Машины MIMD можно подразделить на мультипроцессоры, которые