Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

u_course

.pdf
Скачиваний:
39
Добавлен:
04.06.2015
Размер:
1.87 Mб
Скачать

Средства разработки параллельных программм

11

гопроцессорные SMP-компьютеры (Single Memory Processor) или, например, отдельные узлы компьютеров HP Exemplar и Sun StarFire.

В мультипроцессоре с общей (разделяемой) памятью (SMP) процессо-

ры и модули памяти связаны с помощью соединительной сети (рис. 1.4). Процессоры совместно используют оперативную память, но каждый из них имеет собственный кэш.

Оперативная

Оперативная

память

память

 

Связующая сеть

Кэш

Кэш

ЦПУ

ЦПУ

Рис. 1.4. Структура мультипроцессора с разделяемой памятью

Если число процессоров относительно невелико (от двух до тридцати), связующая сеть реализована в виде шины памяти или матричного коммутатора. Такой мультипроцессор называется однородным (UMA, uniform memory access), поскольку время доступа каждого из процессоров к любому участку памяти одинаково.

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

вается неоднородной (NUMA, non uniform memory access).

ВSMP-компьютерах каждый процессор имеет собственную кэшпамять (кэш), что порождает проблему согласованности кэша. Если два процессора обращаются к одной области памяти примерно одновременно, и один из них записывает данные, то кэш-память этих процессоров будет содержать разные данные, то есть необходимо либо обновлять кэш, либо признать его содержимое недействительным. Протоколы согласования реализуются аппаратно. NUMA-архитектура, обеспечивающая аппаратную поддержку согласованности кэша-памяти, называется ccNUMA – cash caherent non uniform memory access.

ВSMP-компьютерах так же возникает проблема согласованности памяти, решение которой опирается на одну из следующих моделей. Последо-

Средства разработки параллельных программм

12

вательная согласованность гарантирует, что обновление памяти происходит в некоторой последовательности, причем каждому процессору «видна» одна и та же последовательность. Это самая сильная модель. Согласованность процессоров обеспечивает упорядоченность записи в память, выполняемой каждым процессором, но порядок записей, инициированных разными процессорами, для других процессоров могут выглядеть по-разному. Самая слабая модель – согласованное освобождение, при которой оперативная память обновляется в указанных программистом точках синхронизации.

3. Массивно-параллельные компьютеры с распределенной памя-

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

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

В мультипроцессорах с распределенной памятью (MPP, Massively Parallel Processor) каждый процессор имеет свою память, а соединительная сеть поддерживает передачу сообщений, а не чтение и запись в память (рис. 1.5). В такой архитектуре процессоры взаимодействуют, принимая и передавая сообщения, и, следовательно, отсутствуют проблемы согласованности кэша и памяти.

Связующая сеть

Оперативная

Оперативная

память

память

Кэш

Кэш

ЦПУ

ЦПУ

Рис. 1.5. Структура ЭВМ с распределенной памятью

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

Средства разработки параллельных программм

13

Существуют так же гибридные архитектуры. Наиболее общая комби-

нация – машина с поддержкой распределенной разделяемой памяти, то есть распределенной реализации абстракции разделяемой памяти.

4. Другим представителем систем с распределенной памятью является кластер рабочих станций, объединенных коммуникационной сетью, обеспечивающей приемлемую скорость обмена данными. Такие кластеры обычно рассматривают как относительно дешевую альтернативу крайне дорогим суперкомпьютерам.

Последнее направление, строго говоря, не является самостоятельным, а представляет собой комбинации предыдущих трех. Из нескольких процессоров (традиционных или векторно-конвейерных) и общей для них памяти формируется вычислительный узел. Если полученной вычислительной мощности недостаточно, то несколько узлов соединяются высокоскоростными каналами. Подобную архитектуру называют кластерной. Это направление является в настоящее время наиболее перспективным для конструирования компьютеров с рекордными показателями производительности. Все лидеры top500 являются представителями именно такой технологии.

Другой известной схемой классификации компьютерных архитектур является таксономия Флинна, предложенная в 1974 году. В ее основу поло-

жены способы взаимодействия компьютера с потоками команд и данных.

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

1.SISD (Single Instraction Stream – Single Data Stream) – это обычные последовательные компьютеры, в каждый момент времени выполняется только одна операция над одним элементом данных. Возможно включение в состав ВС несколько процессоров, но каждый работает со своим набором данных, относящихся к своей независимой программе.

2.SIMD (Single Instraction Stream – Multiple Data Stream) состоят из од-

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

Средства разработки параллельных программм

14

3.MISD (Multiple Instraction Stream – Single Data Stream). Систоличе-

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

4.MIMD (Multiple Instraction Stream – Multiple Data Stream). Этот класс наиболее богат примерами успешных реализаций. Это и кластеры рабочих станций и симметричные параллельные ВС и пр.

Классификация Флинна не дает исчерпывающего описания разнообразных MIMD архитектур. Например, системы с разделяемой памятью относятся как к MIMD, так и SIMD архитектуре. Поэтому рассматриваются и другие способы классификации параллельных компьютеров, например, Хокни, Фенга, Хендлера, Шнайдера, Скилликорна [3].

РАЗРАБОТКАПАРАЛЛЕЛЬНЫХ ПРИЛОЖЕНИЙ

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

Многопоточные приложения. Термин многопоточный обычно оз-

начает, что программа содержит больше процессов/потоков1, чем существует процессоров для их выполнения. Следовательно, процессы на процессорах выполняются по очереди.

Примерами многопоточных программ являются ОС, системы разделения времени, системы реального времени, многие оконные приложения.

Много

поточные Пр: ОС

Распределенные Пр: файл-сервер, СУБД, Web

Параллельные Пр: научные, графика и

обработка изображений, задачи оптимизации

Рис. 1.6. Классы приложений

1 Мы оставим за рамками обсуждения различия между терминами процесс и поток. Здесь и далее считается, что процесс – это выполняемая в системе программа, решающая некоторую задачу, владеющая и/или претендующая на некоторые ресурсы системы. Ресурсы процессу могут выделяться как в безраздельное пользование (например, адресное пространство), так и разделяться с другими процессами (например, процессор). Поток – это «облегченный» процесс, т.е. потоки имеют собственные счетчики команд, стеки выполнения, но работают в общем адресном пространстве.

Средства разработки параллельных программм

15

Эти системы разрабатываются многопоточными, поскольку составляющие их задачи могут планироваться и выполняться независимо. Например, в MS Word один поток отвечает за проверку орфографии, другой за пересчет ссылок и полей, третий за ввод данных и т.д.

Основной проблемой реализации таких программ является борьба за разделяемые ресурсы, например, процессор, память, устройства ввода-вывода

идругие.

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

Примерами распределенных систем могут служить файловые серверы в сети, СУБД, Web-сервера в сети Internet, отказоустойчивые системы, которые продолжают работать независимо от сбоев в компонентах.

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

такие системы основаны на технологии клиент-сервер, а их компоненты сами являются многопоточными программами.

Синхронизируемые (согласованные) параллельные вычисле-

ния. Цель таких приложений – совместно быстро решить данную задачу. Примерами синхронизируемых параллельных вычислений являются

различные научные вычисления (например, численные модели математической физики), графика и обработка изображений (включая создание спецэффектов в кино), крупные комбинаторные и оптимизационные задачи.

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

В таксономии Флинна уже прослеживается два основных подхода к построению параллельных приложений.

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

Средства разработки параллельных программм

16

в заданный момент времени на всех процессорах выполняется одна и та же инструкция).

2. Параллелизм по задачам предусматривает разбиение вычислительной задачи на несколько самостоятельных подзадач. Компьютер при этом представляет MIMD-машину. Для каждой подзадачи, как правило, пишется своя программа. Подзадачи в ходе работы обмениваются данными, а так же согласуют свою работу. При программировании контролируется распределение данных между процессами/потоками и вычислительной нагрузки между процессорами, что повышает трудоемкость разработки и отладки программы.

Как правило, выбор метода распараллеливания основан на свойствах самой задачи или выбранного алгоритма ее решения. Так, для сеточных вычислений характерен параллелизм по данным, однако можно выбрать такой алгоритм решения (например, метод прогонки для решения СЛАУ с трехдиагональной матрицей), который испортит весь параллелизм исходной задачи. Задача обработки изображения может обладать внутренним параллелизмом по задачам, а каждая задача – параллелизмом по данным.

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

ция (ДСС).

Декомпозиция – это процесс разбиения прикладной задачи на части. Иногда декомпозиция естественным образом следует из природы самой задачи, иногда она определяется разработчиком.

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

Параллелизм можно организовать и на уровне команд (рис. 1.7). Этот вид параллелизма обычно обеспечивается компилятором, ОС и внутренней архитектурой процессора. Обсуждение этих вопросов выходит за рамки нашего пособия.

Следующий уровень параллелизма в итеративных программах – цикл. Не всякий цикл можно выполнять параллельно (см., например, [3]). Решение об этом принимает, как правило, программист, например, с помощью директив компиляции. Эта технология реализована в OpenMP, и будет рассмотрена ниже.

Средства разработки параллельных программм

17

E = (A + B) / (C * D)

E1 = A + B E2 = C * D Параллельное выполнение

Синхронизация

E = E1 / E2

Рис. 1.7. Синхронизация на уровне команд

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

Дальнейшее укрупнение уровня параллелизма – объекты и приложения – характерно для распределенных приложений, которые в этой книге не рассматриваются.

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

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

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

«Гонка данных» возникает из-за того, что несколько задач одновременно пытаются обновить и использовать общие данные. Проблема наиболее очевидна, если данные одновременно перезаписываются. Однако «гонка данных» часто возникает и в случае, когда одна задача должна неоднократно использовать данные, обновляемы в другой задаче. При отсутствии согласованности задача-потребитель может использовать устаревшие данные (при

Средства разработки параллельных программм

18

опережающем чтении) или утерять данные (производитель может при записи затереть еще неиспользованные данные).

Некорректное планирование последовательности выполнения задач приводит и к другой проблеме – «бесконечной отсрочке», при которой задача может никогда не получить возможность выполнится.

«Взаимоблокировка» – еще одна ловушка, связанная с ожиданием. В простейшем случае взаимная блокировка возникает, если «задача 1» ждет данных (сигнала) от «задачи 2», которая в свою очередь ожидает данных от «задачи 1». Однако ситуация может оказаться еще более запутанной.

Все эти проблемы должны быть выявлены и разрешены на стадии проектирования.

ПРОГРАММНЫЕСРЕДСТВА

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

В табл. 1.1 приведен неполный список языков параллельного программирования, библиотек и систем разработки параллельных программ [7,17].

Таблица 1.1 Параллельные языки, библиотеки, системы программирования

для ВС

для систем

объектно – ориен-

параллельные

с разделяемой

с распределенной

тированные

декларативные

памятью

памятью

системы

языки

OpenMP

MPI

C#

Parlog

Linda

PVM

Java

Multilisp

Java

HPF

Qt

Concurrent Prolog

PTHREAD

DVM

Distributed Java

Sisal

SDL

Occam

HPC++

Tempo

DVM

Ada

CA

 

SR

CSP

Charm++

 

 

SR

 

 

 

NESL

 

 

 

ZPL

 

 

Библиотека PTHREAD разработана в 90-х годах прошлого века под эгидой организации POSIX (Portable Operating System Interface – интерфейс переносимой ОС). Она определяет стандартный набор функций языка C для многопоточного программирования.

Средства разработки параллельных программм

19

Язык программирования Java объединяет возможности интерпретируемых, объектно-ориентируемых и параллельных языков, добавляя несколько новых. Он поддерживает как многопоточное, так и распределенное программирование.

Одним из наиболее популярных средств программирования многопроцессорных компьютеров с общей памятью в настоящее время является технология OpenMP. При ее использовании за основу берется последовательная программа. Для создания ее параллельной версии используется набор директив, процедур и переменных окружения. Технология OpenMP представляет программу как последовательность параллельных и последовательных областей, для поддержки параллелизма используя схему FORK/JOINT. Все порожденные нити исполняют один и тот же код параллельной области. Переменные программы разделяются на общие (SHARED) и локальные (PRIVATE). Стандарт OpenMP разработан для языков Fortran, C, C++. Реализация стандарта доступна как для UNIX-платформ, так и в среде Windows.

Язык CSP (Communicating Sequential Processes – взаимодействующие последовательные процессы) впервые описан в 1978 г. Тони Хоаром. Его первое описание содержало идеи синхронной передачи сообщений и защищенного взаимодействия. Язык CSP повлиял на разработку таких языков программирования, как Occam и Ada. Его последняя версия стала формальным языком для моделирования и анализа поведения параллельных систем.

Язык Occam начал разрабатываться в середине 80-х годов для транспьютеров, для которых был, по сути, машинным языком. Язык содержит очень малое число механизмов, что и определило его название (от выражения «бритва Оккама»). Его базовые элементы – декларации и три примитивных процесса (присваивание, ввод и вывод), которые объединяются в обычные процессы с помощью трех типов конструкторов (последовательный, параллельный и защищенное взаимодействие).

Система Linda разработана в середине 80-х годов в Йельском университете США. В рамках системы параллельная программа – это множество параллельных процессов, каждый из которых работает как последовательная программа. Все процессы имеют доступ к общей памяти, единицей которой является кортеж – упорядоченная последовательность значений. Процессы в системе Linda никогда не взаимодействуют друг с другом явно, их общение всегда опосредованно, через пространство кортежей, которое можно считать виртуальной ассоциативной памятью. По замыслу создателей Linda в любой последовательный язык достаточно добавить только четыре функции (извлечь / прочитать элемент из пространства кортежей, поместить элемент в пространства кортежей, вычисляя его последовательно или параллельно). После этого последовательный язык становится средством параллельного

Средства разработки параллельных программм

20

программирования. Несколько языков программирования, включая C и FORTRAN, были дополнены примитивами Linda.

При использовании библиотеки MPI (Message Passing Interface – ин-

терфейс передачи сообщений) процессы распределенной программы записываются на таком последовательном языке, как C или FORTRAN. Их взаимодействие или синхронизация задается с помощью вызова процедур библиотеки. Каждый процессор выполняет копию одной и той же программы, использующей функции MPI. Каждый экземпляр программы может определить собственный идентификатор и, следовательно, выполнять действия, отличные от других.

Система разработки и выполнения параллельных программ PVM (Parallel Virtual Machine – параллельная виртуальная машина) разработана в США в 90-х годах прошлого века. Она позволяет объединить разнородный набор компьютеров, связанных сетью в общий вычислительный ресурс. Единицей параллелизма в PVM является задача, состояние которой изменяется (вычисления, обмен данными и пр.). Выполнение PVM-программы порождает несколько процессов, которые взаимодействуют посредством обмена сообщениями. Система поддерживает языки C, FORTAN, Perl, Java и даже математический пакет Matlab.

HPF (High Performance FORTRAN – высокопроизводительный FORTRAN) – это язык, параллельный по данным. Он является расширением языка FORTRAN-90 для разработки параллельных программ. Основные компоненты HPF – параллельное по данным присваивание массивов, директивы компилятора для управления распределением данных и операторы записи и синхронизации параллельных циклов.

Вообще, языки параллельные по данным (C*, ZPL, NESL) поддерживают стиль программирования, в которых все процессы выполняют один и тот же код на разных частях данных. Некоторые создавались под определенные архитектуры (например, C* тесно связан с архитектурой CM-1, первой SIMD Connection Machine). Они значительно упрощают обработку массивов и матриц. Не смотря на явное взаимодействие процессов, в таких языках синхронизация часто поддерживается неявно, после каждого оператора.

Объектно-ориентированные системы, как правило, поддерживают многопоточность. Например, библиотека C Qt позволяет осуществлять управление потоками добавлением объектов класса QThread.

Особо следует отметить объектно-ориентированные языки, например, C#, Distributed Java, поддерживающие CORBA (Common Object Request Broker Architecture) – стандарт для определения отношений, взаимодействий и связей между распределенными объектами.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]