Научная статья на тему 'Графический метод проектирования параллельных программ с использованием асинхронной событийной модели вычислений'

Графический метод проектирования параллельных программ с использованием асинхронной событийной модели вычислений Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
286
52
i Надоели баннеры? Вы всегда можете отключить рекламу.

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Востокин С. В.

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

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

Текст научной работы на тему «Графический метод проектирования параллельных программ с использованием асинхронной событийной модели вычислений»

Информатика

УДК 681.3.06 С.В. Востокин

ГРАФИЧЕСКИЙ МЕТОД ПРОЕКТИРОВАНИЯ ПАРАЛЛЕЛЬНЫХ ПРОГРАММ С ИСПОЛЬЗОВАНИЕМ АСИНХРОННОЙ СОБЫТИЙНОЙ МОДЕЛИ ВЫЧИСЛЕНИЙ

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

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

Повышение эффективности программ, работающих на компьютерах М1МБ архитектуры с распределенной памятью, часто достигается путем совмещения во времени обменов и вычислений и использования асинхронных коммуникаций [1]. При этом в инструкциях по применению библиотек распространенного стандарта МР1 обычно указывается, что асинхронные коммуникации следует использовать с осторожностью. Как следствие, в практике параллельного программирования используются более надежные, но менее эффективные, модели управления вычислениями, такие, как последовательно-параллельное управление и синхронные вычисления [2].

Выход мы видим в применении формализованного метода проектирования, использующего специальную графическую нотацию. Полученные на стадии проектирования корректные схемы программ затем вручную или автоматически, по специальным правилам, переводятся в код параллельной программы традиционной 8РМБ-модели, диктуемой стандартом МР1. Описанный метод лежит в основе визуального языка параллельного и распределенного программирования ГРАФ ПЛЮС [3].

Предлагаемая модель вычислений относится к группе асинхронных моделей программирования с событийным управлением [4]. Модель программы представляет собой диаграмму. Все обозначения, используемые при моделировании программ, показаны на рис.1.

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

Между событиями вводится отношение непосредственного следования, обозначаемое стрелкой. Если между вершинами А и В имеется стрелка, то это означает, что событие завершения процедуры А является причиной события активации процедуры В. Если некоторое событие

Рис. 1. Обозначения, используемые в логической модели программ

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

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

Рассмотрим задачу решения систем линейных уравнений методом Гаусса-Зейделя, получающихся при дискретизации стационарного уравнения Лапласа методом конечных разностей для двумерного случая [5]. Пусть область, для которой ищется решение, имеет прямоугольную форму. Если принять в качестве условия остановки вычислительного процесса выполнение заданного числа итераций, то алгоритм решения задачи описывается программой на языке Си, представленной на рис.2.

#define SCAN_CUR (i*hight+j)

#define SCAN_UP (i*hight+j-1)

#define SCAN_DOWN (i*hight+j+1)

#define SCAN_LEFT ((i-1)*hight+j)

#define SCAN_RIGHT ((i+1)*hight+j)

// инициализация int i,j,t;

for(

for(

for(

{

matrix[

matrix[

matrix[

matrix[

matrix[

Не рассматривая физического и математического аспекта данной задачи, выполним распараллеливание алгоритма, описываемого программой. Анализ такого рода алгоритмов удобно проводить с использованием шаблонов.

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

Пусть имеется 8МР компьютер с двумя процессорами, работающими над общей памятью. Выполним разбиение матрицы следующим образом. Разделим матрицу пополам на два сегмента — правый и левый. По обе стороны от линии разбиения дополнительно выделим по одному столбцу элементов матрицы. В итоге получим разбиение матрицы на четыре области, показанное на рис.4.

На основе разбиения области данных проведем декомпозицию алгоритма на процедуры. Процедура СВ1 выполняет однократный пересчет всех элементов левого сегмента матрицы, используя направление обхода элементов, показанное на рис.3, начиная с верхнего левого, заканчивая правым нижним элементом. Процедура СЬ1 выполняет однократный пересчет левого столбца сверху вниз. Процедура СЬ2 выполняет одно-

пропущена

;t<maxcount;t++)// число итераций до остановки ;i<width-1;i++)// цикл по ширине ;j<hight-1;j++)// цикл по высоте

SCAN_CUR]=0.25*(// SCAN_UP]+// значение в SCAN_DOWN]+// значение SCAN_LEFT]+// значение SCAN RIGHT]// значение

значение в точке і в точке в точке в точке

точке j-1 i j+1 i-1 j i + 1 j

i j

Рис .2. Фрагмент последовательной программы на языке Си

і И-' J*1-1

J-1*1

Рис .3. Пятиточечный шаблон и направление обхода матрицы

О

CL1 /■ "ч

%

Рис .4. Разбиение матрицы на четыре области и процедуры пересчета областей

кратный пересчет правого столбца по направлению сверху вниз. Наконец, процедура СВ2 выполняет однократный пересчет всех элементов правого сегмента матрицы аналогично процедуре СВ1. Связь процедур и сегментов матрицы показана на рис.4. Нетрудно заметить, что, выполняя в цикле последовательность процедур СВ1, СЬ1, СЬ2, СВ2, получим исходный алгоритм пересчета.

Если в нашем распоряжении имеется два компьютера с распределенной памятью, то разбиение области данных будет выглядеть следующим образом. На рис. 5 показано, что первые две области матрицы (считая слева направо) будут размещены в локальной памяти одного компьютера, а вторые две области — в памяти другого компьютера. Кроме этого, для того, чтобы шаблоны процедур СЬ1 и СЬ2 оставались внутри матриц, соответствующие области расширены так называемыми «теневыми» столбцами.

Набор процедур для случая распределенной памяти расширен процедурами Т1 и Т2. Назначение этих процедур — управлять синхронизацией теневых столбцов со столбцами, копии значений которых они содержат. Процедура Т1 выполняет копирование значений из столбца, находящегося слева, в «теневой» столбец, находящийся справа. Процедура Т2 выполняет копирование значений из столбца, находящегося в области памяти справа, в «теневой» столбец, находящийся с области памяти слева. Направление копирования показано на рис.5. Можно заметить, что аналогично случаю с общей памятью, выполняя в цикле последовательность процедур СВ1, Т2, СЬ1, Т1, СЬ2, СВ2, получим исходный алгоритм пересчета.

Передача значений между разными областями памяти организуется путем посылки сообщений. Заметим, что в случае разделяемой памяти в процессе счета также присутствуют «теневые» области и передача данных. Сам процесс реализуется не алгоритмически, а аппаратурой 8МР компьютера, а роли локальных, по отношению к процессору областей памяти, выполняют кэш-памяти процессоров. Поэтому разбиение на процедуры, показанное на рис.5, представляет собой обобщение архитектур с общей и распределенной памятью применительно к нашей задаче. В итоге получаем декомпозицию исходной программы в виде набора из шести процедур СВ1, Т2, СЬ1, Т1, СЬ2, СВ2. Для каждой из процедур определена семантика в терминах исходной задачи. Полученные процедуры в дальнейшем будем использовать в качестве базовых элементов для синтеза параллельных алгоритмов в терминах асинхронной событийной модели.

Модель последовательно-параллельного вычислительного процесса представлена на рис.6. Для объяснения модели вновь обратимся к рис. 4 и рис. 5. Рассмотрим две соседние по времени итерации алгоритма. Можно заметить, что когда шаблон первой из итераций проходит середину области данных, шаблон следующей итерации может начинать движение в левой части области данных, не дожидаясь завершения первой итерации. Так как области данных, обрабатываемые процедурами СВ1 и СВ2, независимы, эти процедуры можно запускать одновременно. При этом СВ2 досчитывает текущую итерацию, а СВ1 начинает вычислять следующую итерацию.

Последовательно-параллельный алгоритм

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

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

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

Модель асинхронного вычислительного процесса представлена на рис.7. Аналогично последовательно-параллельной модели исполнения источником параллелизма является возможность одновременного вычисления двух соседних итераций алгоритма процедурами CB1 и CB2.

Рассмотрим последовательность рассуждений, на основе которых строится модель рис.7. В начале определяем все процедуры вычислительного процесса и размещаем их на поле диаграммы. Последовательно рассматриваем все процедуры и соответствующие им события активации. Для каждого события активации на основании логики работы алгоритма находим события завершения тех процедур, которые должны являться причиной данного события активации. Если такое событие завершения одно, то строим дугу, ведущую из вершины события завершения к дуге рассматриваемого события активации. Если событий завершения несколько, то: 1) строим вершину синхронизации и присваиваем ей имя; 2) соединяем вершину синхронизации дугой, ведущей к вершине рассматриваемого события активации; 3) указываем число обнаруженных событий завершения в вершине синхронизации; 4) от вершины каждого выявленного события завершения процедуры проводим дугу к вершине синхронизации. После определения всех отношений непосредственного следования между процедурами, находим начальные события активации процедур и соединяем соответствующие вершины с вершиной начального события.

В случае нашего алгоритма, на основании рис.5, порядок рассуждения может быть таким. Процедуру CB1 можно запустить сразу по завершению CL1. Строим дугу CL1—CB1. Процедуру CL1 можно запустить сразу по завершению CB1 и T2. Строим дополнительную вершину S1 (2) и проводим дуги CB1—S1, T2—S1, S1—CL1. Процедуру CB2 можно запустить сразу по завершению CL2. Строим дугу CL2—CB2. Процедуру CL2 можно запустить сразу по завершению CB2 и T1. Строим дополнительную вершину S2(2) и проводим дуги CB2—S2, T1—S2, S2—CL2. Процедуру T1 можно запустить после CL1, а T2 можно запустить после CL2. Строим дуги CL1—T1 и CL2—T2. Завершаем построение, соединяя вершины CB1, T2 и S2 с начальной вершиной.

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

На основе графических моделей рис.6 и рис.7 построим параллельные программы. В качестве целевой платформы будем использовать двухпроцессорный SMP компьютер под управлением операционной системы Microsoft Windows 2000. Параллельное исполнение в данной архитектуре организовано на основе потоков или нитей (threads). Поток исполняет процедуру, процедуры разных потоков могут обращаться к одним и тем же данным и синхронизировать свою работу при помощи функций синхронизации операционной системы. В параллельной программе, таким образом, нужно: 1) использовать, по крайней мере, два потока; 2) разделить код на две процедуры; 3) организовать синхронизированную работу процедур.

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

А

Рис .7. Модель асинхронного вычислительного

процесса

рис.8. Несложно убедиться, что данная программа эквивалентна исходной программе на рис.6. Процедура первого потока тогда будет исполнять вершины S1, CB1, T2, CL1. Процедура второго потока будет исполнять вершины T1, CL2, CB2, S2.

В любой современной операционной системе, управляющей SMP компьютером, есть функции синхронизации при помощи событий. Для OC Microsoft Windows 2000 вершины синхронизации будут соответствовать объектам «событие» (event) и вызовам функций WaitForSingleObject(hEventR,INFINITE) и WaitForSingleObject(hEventL,INFINITE). Связи между процедурами потоков по дугам CL2—(2)—S1 и CL1—(1)—S2 будут отображаться в вызовы функций синхронизации SetEvent(hEventR) и SetEvent(hEventL).

Для асинхронной модели (рис.6) процедуры CB1, CL1, S1 будут исполняться одним потоком, а CB2, CL2, S2 — другим потоком. При этом процедуры обмена данным T1 и T2 будут исполняться аппаратурой SMP компьютера. Если потребуется перенести код для исполнения в архитектуре с распределенной памятью, они отобразятся в вызовы функций передачи сообщений.

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

Мы провели четыре серии из 81-го вычислительного эксперимента. Размер области расчета изменялся от 10x80 точек до 800x80 точек. Разбиение исходной области выполнялось поровну вдоль размерности 80. В каждом эксперименте проводилось по 10000 итераций до остановки. Результаты вычислительных экспериментов показаны на рис.9.

По рис.9 можно проследить, что в интервале примерно от 10 до 410 точек времена счета последовательного и параллельных алгоритмов отличаются в 1,5 — 2 раза и линейно растут. Далее эффективность последовательного алгоритма резко падает.

Можно также видеть, что при достижении размера в 800 точек эффективность параллельных алгоритмов также начинает падать.

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

Размер матрицы по Х

Рис. 9. Время счета для различных способов организации вычислений

Ш-

Рис .8. Модель последовательно-параллельного вычислительного процесса с разделением на подпроцессы

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

Из рис.9 можно сделать вывод, что для нашего компьютера рассмотренный последовательный алгоритм подходит только для матриц размером не более 80x400 точек, а параллельные алгоритмы — для матриц размером не более 80x800 точек. Для матриц больших размеров требуется разрабатывать специальные эффективные алгоритмы с большей «локальностью» обращения к памяти. Разработка таких алгоритмов — предмет специального изучения. Адекватное же сравнение наших алгоритмов возможно в диапазоне 10 — 400 точек.

Сравним алгоритмы в диапазоне от 10 до 400 точек по критерию ускорения. Под ускорением будем понимать отношение времени счета последовательного алгоритма к времени счета параллельного алгоритма. Значения ускорений показаны на рис.10. На рис.9 и рис.10 дополнительно приведены результаты для «не оптимизированного» асинхронного алгоритма. Это модель программы автоматически построенной по графической модели алгоритма. Такое построение используется в языке ГРАФ ПЛЮС [3]. При

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

Таким образом, асинхронные алгоритмы, построенные с использованием предложенного графического метода, оказываются более эффективными, чем последовательно-параллельные. Хотя 8МР компьютер с общей памятью в значительной мере компенсирует недостатки последовательно-параллельного алгоритма, при переходе к модели с распределенной памятью потери производительности будут более значительными, и его применение становится нерациональным.

БИБЛИОГРАФИЧЕСКИЙ СПИСОК

змер матри

Рис. 10. Значения ускорений для различных способов организации вычислений

1. Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. Спб: Изд-во "БХВ-Петербург", 2002. 608 с.

2. Вальковский В.А., Котов В.Е., Марчук А.Г. и др. Элементы параллельного программирования. М.: Радио и

связь, 1983. 239с.

3. Востокин С.В. Спецификация языка программирования ГРАФ ПЛЮС. Самара: СНЦ РАН, 2003. 86с.

4. Марчук В.А., Нестеренко Б.Б. Асинхронные методы параллельных вычислений / Под. ред. А.М. Самойленко. Киев: Ин-т математики НАН Украины. 1998. 307 с.

5. Самарский А.А., НиколаевЕ.С. Методы решения сеточных уравнений. М.:Наука,1978. 561с.

Поступила 11.03.2004 г.

i Надоели баннеры? Вы всегда можете отключить рекламу.