Книга руденко, Волкова

advertisement
Ю. М. РУДЕНКО, Е.А. ВОЛКОВА
ВЫЧИСЛИТЕЛЬНЫЕ СИСТЕМЫ
T2
0
T3
10
1
9
T9
8
T8
T4
2
3
7
4
6
T7
5
T1
T3, T5
T4, T6
Ю.М. Руденко, Е.А. Волкова
Вычислительные
системы
Архитектура и составляющие её компоненты
Представление параллельных алгоритмов и
оптимизация времени их решения
Москва
Издательство МГТУ имени Н.Э.Баумана
2009
УДК 685.32:519.68(075.8)
ББК
Рецензенты
Руденко Ю.М., Волкова Е.А.
Вычислительные системы.
Предлагаемое учебное пособие рассматривает вопросы, связанные с разработкой и
эксплуатацией вычислительных систем. Подробно излагаются проблемы оценки
производительности и другие эксплутационные характеристики этих систем, принципы
технической реализации, архитектурные свойства и структурные характеристики.
Приведены описания наиболее удачных, на наш взгляд, коммуникационных сред и
коммутаторов. Даны краткие описания параллельных библиотек «Open MP» и «MPI». В
нём представлена вторая составляющая процесса решения параллельных задач представление параллельных алгоритмов с помощью граф-схем, методы построения
ветвей параллельных алгоритмов и размещение их в узлах вычислительных систем.
Учебное пособие предназначено для студентов и магистров технических высших учебных
заведений, университетов, а так же аспирантов и научных работников, работающих в этом
направлении, и написано на основании цикла лекций, читаемых в МГТУ им. Н. Э.
Баумана.
© Издательство МГТУ имени Н.Э.Баумана
3
Оглавление
ГЛАВА 1. АРХИТЕКТУРА ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМ ................................................9
1.1. Количественные характеристики, применяемые для оценок параметров
вычислительных систем............................................................................................................9
1.1.1. Вопросы к разделу 1.1. ......................................................................................................13
1.2. Понятие о современных вычислительных системах .................................................13
1.2.1 Вопросы к разделу 1.2. ....................................................................................................16
1.3. Структура современных вычислительных систем ....................................................16
1.3.1. Схема обмена с помощью структуры «Общая шина» .................................................17
1.3.2. Схема обмена с помощью структуры «Линейка»........................................................17
1.3.3. Вычислительная система, имеющая структуру типа «Кольцо».................................18
1.3.4. Схема обмена с помощью структуры типа «Решётка» ................................................18
1.3.5. Схема обмена с помощью структуры типа «Двумерный тор» .....................................19
1.3.6. Схема обмена с помощью структуры типа «n-мерный двоичный гиперкуб» или
«nD-куб» .......................................................................................................................................20
1.3.7. Реализация обмена с помощью структуры типа «Обобщенный nD-куб».................21
1.3.8. Структура ВС типа «N-мерный обобщённый тор» ......................................................21
1.3.9. Структура ВС с сетью типа «Циркулянт» .....................................................................22
1.3.10. Вычислительная система «Максимальный обхват» ...................................................23
1.3.11. Вычислительные системы со структурой сетей типа «Симметричные графы» .......24
1.3.12. Вычислительные системы с сетью связей типа «Гомоморфные графы» ..................25
1.3.13. Вычислительные системы с сетью связей типа «Граф Л(N,v,g)» ...............................28
1.3.14. Структура вычислительной системы типа «Бинарное дерево T0(n) глубины n» ....37
1.3.15. Структура вычислительной системы типа «Мультидерево глубины n и
ширины k T1(n,k)» ......................................................................................................................38
1.3.16 Вопросы к разделу 1.3 .....................................................................................................39
1.4. Коммуникационные среды вычислительных систем ...............................................39
1.4.1. Коммуникационная среда на основе масштабируемого когерентного
интерфейса SCI ............................................................................................................................40
1.4.2. Коммуникационная среда на основе технологии Myrinet ...........................................41
1.4.3. Краткая характеристика коммуникационной среды QsNet II .......................................42
1.4.4 Вопросы к разделу 1.4 .....................................................................................................44
1.5. Коммутаторы вычислительных систем ......................................................................44
1.5.1. Типы коммутаторов..........................................................................................................44
1.5.2 Управление коммутаторами ...........................................................................................47
1.5.3 Алгоритмы определения маршрутов .............................................................................48
1.5.4 Дедлоки в составных коммутаторах ..............................................................................48
1.5.5 Вопросы к разделу 1.5 .....................................................................................................49
1.6 Процесс функционирования вычислительных систем..............................................49
1.6.1 Вопросы к разделу 1.6. ....................................................................................................50
1.7 Принципы технической реализации ВС .....................................................................50
1.7.1. Вопросы к разделу 1.7 .......................................................................................................52
1.8. Архитектурные особенности ВС ...................................................................................52
1.8.1. Архитектурные свойства ВС ..........................................................................................52
1.8.2. Схема обмена информацией между ветвями параллельных алгоритмов ................53
1.8.3. Опыт применения методики крупноблочного распараллеливания сложных задач .56
1.8.4. Архитектурные аспекты при создании ОС ВС .............................................................56
1.8.5. Структурные характеристики ВС ..................................................................................57
1.8.6. Классификация структур ВС ..........................................................................................58
1.8.7. Вопросы к разделу 1.8. ....................................................................................................60
4
ГЛАВА 2. РЕАЛИЗАЦИЯ ПАРАЛЛЕЛЬНЫХ АЛГОРИТМОВ ............................................61
2.1. Реализация параллельных алгоритмов ..........................................................................61
2.1.1. Определение параллельного алгоритма ..........................................................................61
2.1.2. Организация динамического распараллеливания в суперскалярных
микропроцессорах .......................................................................................................................62
2.1.3. Предварительная выборка команд и предсказание переходов ....................................64
2.1.4. Декодирование команд, переименование ресурсов и диспетчеризация ....................64
2.1.5. Исполнение команд .........................................................................................................65
2.1.6. Работа с памятью ............................................................................................................66
2.1.7. Завершение выполнение команды .................................................................................68
2.1.8. Направления развития суперскалярной архитектуры ..................................................68
2.1.9. Мультитредовая модель выполнения программы ........................................................70
2.1.10. Аппаратные и программные средства, необходимые для мультитредовой
архитектуры .................................................................................................................................71
2.1.11. Специфика мультитредовых моделей распараллеливания .........................................73
2.1.12. Вопросы к разделу 2.1 .....................................................................................................74
2.2.Организация распараллеливания на уровне программных модулей............................74
2.2.1. Примеры организации вычислений на уровне программных модулей .....................74
2.2.2. Решение системы линейных уравнений методом Гаусса с помощью ВС типов
«решётка» и «линейка» ...............................................................................................................86
2.2.3. Исполнение алгоритма Гаусса на «решётке» n*n ВM ...................................................88
2.2.4. Исполнение алгоритма Гаусса на «линейке», состоящей из n ВМ ..............................89
2.2.5. Показатели эффективности параллельных алгоритмов ................................................91
2.2.6. Понятие о сложных задачах .............................................................................................92
2.2.7. Вопросы к разделу 2.2 .......................................................................................................93
ГЛАВА 3. НАДЕЖНОСТЬ И ЖИВУЧЕСТЬ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМ ..................94
3.1. Основные задачи создания отказоустойчивых систем .............................................94
3.1.1 Вопросы к разделу 3.1 .....................................................................................................94
3.2. Классификация типов отказоустойчивости сложных систем и ее критерии ..........95
3.2.1 Вопросы к разделу 3.2 .....................................................................................................97
3.3. Способы обеспечения отказоустойчивого функционирования ВС .........................98
3.3.1. Диагностическое тестирование ВС..................................................................................99
3.3.3. Способы восстановления отказоустойчивых ВС .........................................................101
3.3.4 Вопросы к разделу 3.3 ...................................................................................................102
3.4. Построение живучих ВС на основе экспоненциально- надежностного подхода ...103
3.4.1. Показатели надежности ВС ............................................................................................105
3.4.2. Методика расчета показателей надежности ВС .........................................................105
3.4.3. Живучесть ВС ..................................................................................................................107
3.4.4. Вопросы к разделу 3.4 ....................................................................................................110
3.5. Построение живучих ВС, работоспособных в расчетном диапазоне кратностей
отказов ....................................................................................................................................110
3.5.1. Вопросы к разделу 3.5 ....................................................................................................114
3.6. Реализация модели отказоустойчивых систем ............................................................114
3.6.1. Горячий резерв .................................................................................................................114
3.6.2. Репликация ......................................................................................................................115
3.6.3. Кластеры высокой готовности .......................................................................................115
3.6.4. Вопросы к разделу 3.6 .....................................................................................................117
ГЛАВА 4. БИБЛИОТЕКА ПАРАЛЛЕЛЬНЫХ ПРОГРАММ ...............................................118
4.1 Характеристика параллельных языков программирования ........................................118
4.1.1 Характеристика спецификаций OpenMP .....................................................................118
4.1.2. Принципиальная схема программирования в OpenMP ...............................................119
4.1.3. Описание основных конструкций OPEN MP ..............................................................121
5
4.1.4. Способы построения параллельных программ.............................................................126
4.1.5 Спецификация OpenMP для языков C и C++ ..............................................................128
4.1.6. Вопросы к разделу 4.1 ....................................................................................................129
4.2. Основы построения библиотеки MPI ...........................................................................130
4.2.1. Основные понятия ...........................................................................................................130
4.2.2. Структура программ в MPI.............................................................................................132
4.2.3. Определение структуры приходящего сообщения .....................................................135
4.2.4. Определение базовых характеристик коммуникационной сети ................................ 136
4.2.5 Анализ тупиковых ситуаций при обмене ....................................................................138
4.2.6. Организация передачи-приёма сообщений без блокировки ......................................139
4.2.7. Реализация отложенных запросов на взаимодействие ...............................................141
4.2.8. Сравнительная оценка различных способов обмена данными ...................................142
4.2.9. Использование глобальных операций в MPI ...............................................................143
4.2.10. Взаимодействие процессов в MPI ................................................................................143
4.2.11. Вопросы к раделу 4.2 ...................................................................................................146
ГЛАВА 5. Граф-схемы параллельных алгоритмов ................................................................ 147
5.1. Представление параллельных алгоритмов в виде граф-схем ....................................147
5.1.1. Преобразование последовательных алгоритмов в параллельные ..............................147
5.1.2.Использование граф-схем для представления параллельных алгоритмов .................157
5.1.3. Вопросы к разделу 5.1 .....................................................................................................159
5.2.1. Вычисление матриц следования, расширенных матриц следования и матриц
следования с транзитивными связями .....................................................................................159
5.2.2. Вопросы к разделу 5.2 .....................................................................................................168
5.3.1. Построение матрицы логической несовместимости. .................................................168
5.3.2. Построение матрицы логической несовместимости операторов ...............................172
5.3.3. Вопросы к разделу 5.3 .....................................................................................................174
5.4.1. Построение множеств взаимно независимых операторов. .........................................175
5.4.2. Вопросы к разделу 5.4 .....................................................................................................177
ГЛАВА 6. Исследование информационных граф-схем со скалярными весами для
планирования параллельных вычислений ...........................................................................178
6.1. Численные характеристики информационных граф-схем со скалярными весами ..178
6.1.1 Определение ранних и поздних сроков окончания выполнения операторов. ...........178
6.1.2. Определение функций плотности загрузки, и минимальной загрузки для
информационных граф-схем ....................................................................................................181
6.1.3. Вопросы к разделу 6.1 .....................................................................................................184
6.2.1. Распределение операторов по ВМ вычислительной системы с общим полем памяти
для информационной граф-схемы ...........................................................................................185
6.2.2. Распределение операторов по ВМ вычислительной системы с общим полем памяти
для информационно-логической граф-схемы .........................................................................188
6.2.3. Распределение операторов по ВМ вычислительной системы с распределённой
памятью для информационной граф-схемы ...........................................................................190
6.2.4. Реализация диаграмм для общепринятых способов обмена данными между ВМ
вычислительной системы с распределённой памятью для информационной граф-схемы196
6.2.5. Вопросы к разделу 6.2 .....................................................................................................198
ГЛАВА 7. Исследование информационных граф-схем решаемых задач с векторными
весами для планирования параллельных вычислений .........................................................200
7.1 Информационная граф-схема решаемых задач с векторными весами вершин ....200
7.1.1 Понятие об неоднородных системах .............................................................................200
7.1.2. Основные определения, используемые для неоднородных ВС ..................................202
7.1.3. Вопросы к разделу 7.1 .....................................................................................................205
Литература .................................................................................................................................206
6
Введение
Повышение быстродействия вычислительных систем (ВС) является актуальнейшей
задачей современной науки и техники. В данной работе будут рассматриваться
архитектура ВС, как совокупность вычислительных модулей (ВМ), и методы их
организации. Под вычислительным модулем (ВМ) будем понимать процессор или ЭВМ.
Не менее важным вопросом является планирование параллельных вычислений
применительно к ВС, созданных на базе фон-неймановских или гарвардских архитектур,
которые в настоящее время получили наибольшее распространение. В основу первой и
второй главы предлагаемого учебного пособия положены материалы работ [1,2] и
собственные исследования автора. Глава третья представляет собой существенно
переработанные в соответствии с духом времени идеи и методы, предложенные в [3,4].
Более подробное описание рассматриваемых вычислительных устройств, а также
программ приводится в соответствующей цитируемой литературе и в интернете.
Процесс создания быстродействующих ВС развивается по трем основным
направлениям:
1. Совершенствование элементной базы ВС:
1.1. Использование сверхбольших (СБИС) и гипербольших интегральных схем
(ГБИС) с все увеличивающейся плотностью активных элементов (транзисторов) на
единицу площади и скоростью их срабатывания;
1.2. внедрение в СБИС оптоэлектронных элементов;
1.3. перевод СБИС на работу в оптическом диапазоне.
2. Совершенствование архитектур ВС.
2.1. Широко используемые ВС, построенные на основе вычислителей классических
фон-неймановских и гарвардских архитектур совершенствуются за счёт сокращения
времени доступа к обрабатываемым данным, уменьшением времени выполнения
инструкций процессоров. Особенно перспективным является создание архитектур,
позволяющих распараллеливать вычисления на различных уровнях. Различаются три
класса ВС: симметричные мультипроцессоры (SMP), кластеры и массово–параллельные
системы (МРР).
2.1.1. Симметричные мультипроцессоры включают в себя совокупность
процессоров, имеющих общее поле памяти с единым адресным пространством.
2.1.2. Кластеры состоят из совокупности процессоров, объединённых либо сетью
или разделённые устройствами внешней памяти. Используются, например, средства
MEMORY CHANNAL фирмы DEC, AWS фирмы NCR, или локальные, универсальные и
глобальные сети, такие как Ethernet, FDDI (Fiber distributed Data Interface), сети с
протоколами TCP/IP (Transmission Control Protocol/Internet Protocol), или дисковые
массивы с высокоскоростными двойными и квадро PCI SCSI контролерами. Кластер
может включать до нескольких сотен вычислителей и обеспечивать живучесть при
отказах некоторых элементов его оборудования.
2.1.3. Массово – параллельные системы характеризуются высокой пропускной
способностью, возможностью совмещения передач информации с одновременной её
обработкой,
поддержание
различных
топологий,
масштабируемость
и
конфигурируемость.
3. Развитие архитектур ВС, использующих другие принципы обработки данных. В
качестве примера можно привести ВС, использующие нейронные, ассоциативные
процессоры [10,11].
4. Создание новых вычислительных методов и алгоритмов, позволяющих
сокращать время получения требуемой величины, ориентированные на использование
современных архитектур ВС.
Следует отметить, что эти четыре основных направления связаны друг с другом,
взаимно дополняют друг друга. Так, например, при создании СБИС гораздо проще
7
реализовать периодические структуры электронных схем. Это же свойство сушественно
упрощает проектирование ВС для параллельных вычислений.
Разработка архитектур параллельных ВС требует создания новых вычислительных
методов и алгоритмов и, наоборот, некоторые эффективные вычислительные методы
порождают новые архитектуры ВС.
Специфика использования оптических БИС требует разработки принципиально
новых методов и средств обработки данных и т. д.
В связи с появлением вычислительных систем (ВС) актуальнейшей проблемой
стала разработка параллельных алгоритмов и программ, которые являются основными,
чуть ли не главными компонентами этих систем. Решение этих проблем поставило перед
разработчиками много новых проблем. В частности, в казалось бы более или менее
законченной области человеческих знаний – математике потребовалось создание новых
методов, позволяющих вычислять требуемые результаты, получая промежуточные данные
одновременно на нескольких ВМ. Второй важной проблемой является создание на базе
существующих математических методов параллельных алгоритмов решения задач на ВС,
учитывающих архитектуры используемых ВС. Третьей важной проблемой является
создание эффективных параллельных языков программирования. Конечно, список
проблем на этом не заканчивается и можно продолжать этот список ещё достаточно долго.
Темой исследования данной работы являются способы представления
параллельных алгоритмов, также методы отображения этих алгоритмов на структурах ВС.
Было бы неправильно забыть о громадном количестве программ, которые были созданы
для ЭВМ, поэтому в начале этой работы предлагаются методы и алгоритмы для
преобразования последовательных алгоритмом и программ в параллельные. Это
преобразование во многих случаях может вызвать большие затруднения, так как
параллельная программа должна быть представлена в виде совокупности процедур и
функций. Обмен данными между ними должен осуществляться с помощью аппарата
формально – фактических параметров. Использование глобальных параметров различных
уровней проблематично, так как затушёвывается зависимость по данным между
процедурами и функциями. Выделить участок программы, и оформить его в виде
процедуры или функции для создания параллельной секции, как это делается в Open MP,
и добиться от этого выделения некоторого эффекта при распараллеливании, может только
программист. Транслятор в этом случае может создавать параллельные ветви только для
циклов по счётчику циклов. Безусловно, здесь также надо учитывать, что реализация
программы на ВС требует, как правило, гораздо больших накладных расходов, поэтому не
всякое преобразование последовательной программы в параллельную может быть
эффективно и требует предварительных оценок при выборе структур ВС для решения
рассматриваемой задачи. Для тех, кто имел дело с представлением параллельных
алгоритмов с помощью схем алгоритмов по ГОСТ 19.003-80 ЕСПД, ГОСТ 19.701-90
ЕСПД, было понято, что эти схемы мало соответствуют требованиям к изображению
параллельных алгоритмов и способов их отображения на структуры ВС. Поэтому в
данной работе предлагается дополнение к этим ЕСПД для изображения алгоритмов в виде
граф-схем, которые легко отображаются на структуры ВС с помощью библиотек
Open MP, MPI и др. Конфигурации граф-схем позволяют представить в удобной форме
все существующие операторы последовательных языков программирования, а также
представлять схемы обмена данными между ВМ. На базе граф-схем создаются различные
схемы анализа параллельных алгоритмов: матрицы следования, множества взаимно
независимых операторов, внешние и внутренние замыкания в граф-схемах, определения
минимального количества ВМ, обеспечивающих минимальное время решения задачи,
построение нитей в граф-схемах алгоритмов решаемой задачи, распределение нитей
по ВМ и т.д.
8
ГЛАВА 1. АРХИТЕКТУРА ВЫЧИСЛИТЕЛЬНЫХ
СИСТЕМ
1.1. Количественные характеристики, применяемые для оценок
параметров вычислительных систем
Широко распространённым и наиболее простым показателем эффективности
вычислительных модулей является тактовая частота, которая показывает, сколько
элементарных операций может быть выполнено в единицу времени (обычно – в секунду).
Элементарная операция, например, — это опрос регистра, запись кода числа в разряд
регистра, учёт единицы переноса в одном разряде сумматора. В настоящее время частота
может измеряться в герцах, килогерцах, мегагерцах, гигагерцах и т.д. Соотношение
между этими единицами и принятые обозначения выглядят следующим образом (в
круглых скобках приведено обозначение на английском языке):
1 МегаГц (MegaHz) = 1 МГц (MHz)= 10 6 Гц (Hz),
1 ГигаГЦ (GigaHz ) = 10 3 (МГц) MHz = 109 Гц (Hz).
Очевидно, что этот параметр может характеризовать вычислительную систему
только приблизительно. Если взять тактовую частоту и умножить на количество
вычислительных модулей в системе (или усреднённую тактовую частоту для
неоднородных систем), то можно получить некоторое представление о
производительности ВС. Следует отметить, что при этом не будут учтены архитектурные
особенности вычислителей, коммуникационных сред и характер задач, которые будут
решаться на данной вычислительной системе. Кажется целесообразным перенести все
вычисления производительностей вычислительных модулей
на определения
производительности ВС, произведя необходимые коррекции. Дело в том, что решение
задачи на вычислительных устройствах аналогичны по организации вычислений. Вначале
осуществляется ввод данных, преобразование их, затем, собственно, обработка. В связи с
этим методы, используемые для оценок производительности вычислительных модулей, с
некоторыми уточнениями можно использовать для оценок производительности ВС.
Безусловно, ВС имеют более сложную структуру, поэтому при оценке
производительности необходимо учесть архитектурные свойства ВС, класс решаемых
задач и степень соответствия класса решаемых задач архитектуре ВС.
Количество операций в секунду является основной величиной для определения
производительности
вычислительных
устройств.
Единицами
измерения
производительности над числами с фиксированной точкой являются
1 MIPS(millions of instructions per second) = 10 6 операций/секунду;
1 GIPS = 109 операций/секунд.
(1.1.1)
Длительность арифметической операции над числами с плавающей точкой
существенно больше при прочих равных условиях, поэтому в этих случаях используются
другие единицы:
1 FLOPS (floating point operations per second) = 1 операция
с плавающей точкой/секунду
1 MegaFLOPS = 1 M FLOPS = 10 6 FLOPS (миллион операций
с плавающей точкой/секунду)
1 GigaFLOPS = 1 G FLOPS = 109 FLOPS (миллиард операций
с плавающей точкой/секунду)
1 TeraFLOPS = 1 T FLOPS = 1012 FLOPS (триллион операций
с плавающей точкой/секунду )
(1.1.2)
9
1 PetaFLOPS = 1 P FLOPS = 1015 FLOPS (квадриллион операций
с плавающей точкой/секунду )
В реальных условиях в решаемых задачах используются арифметические операции
над целыми числами, над числами с плавающей точкой. В этом случае используется
номинальное или пиковое быстродействие, которое определяется как
k
,
(1.1.3)
p  k
tj
j 1
где k – количество выполняемых операций, t j – время выполнения j-й операции из
множества операций R вычислительного модуля. При вычислении n операций вводавывода информация с внешних устройств не учитывается. Для однородной ВС этот
показатель выразится в виде:
k *N
,
(1.1.4)
 *p  k
*
t j
j 1
где N – количество вычислительных модулей в однородной ВС, k – количество
выполняемых операций, t *j – время выполнения j-й операции из множества операций R
вычислительного модуля.
Для случая неоднородной системы номинальное быстродействие выразится как
n
(k * N )
н
(1.1.5)
 p  (  ( iki i )) / n ,
*
i 1
 t ji
ji 1
где Ni – количество вычислительных модулей i–го типа в неоднородной системе, ki –
операции, выполняемые i-м типе вычислительного модуля, n – число типов
вычислительных модулей, t *ji – время выполнения j-й операции на i-м типе ВМ.
В случае не равновероятного выбора операций используется быстродействие
вычислительного модуля по Гибсону:
1
,
(1.1.6)
g  k
t j p j
j 1
Здесь p j – вероятность выбора j-й операции, j  1, k ,
k
p
j 1
j
 1.
Для однородной ВС её быстродействие по Гибсону выразится соотношением
N
,
(1.1.7)
 g*  k
*
tj pj
j 1
где N – количество вычислительных модулей в однородной системе, t*j – время
выполнения j-й операции из множества операций R вычислительного модуля, рj –
вероятность выполнения j-й операции.
Для неоднородной ВС это быстродействие может быть определено, как
n
N
(1.1.8)
 gн  (  ( ki i )) / n,
*
i 1
 t ji p j i
ji 1
10
где Ni – количество вычислительных модулей в неоднородной системе, ki – операции,
выполняемые на i-м типе вычислительного модуля, n – число типов вычислительных
модулей, t *ji – время выполнения j-й операции на i-м типе вычислительного модуля, p ji –
вероятность выполнения j-й операции на i-м типе вычислительного модуля.
Вероятности p j , или p ji ещё называют весовыми коэффициентами. Существуют
определённые наборы коэффициентов, которым соответствуют наборы тестов – т.н. смеси
Гибсона.
Если соотношения (1.1.3 – 1.1.8) применяются только к арифметическим
операциям над целыми числами, то единицей измерения служит MIPS или GIPS согласно
соотношению (1.1.1). В остальных случаях (для чисел с фиксированной и плавающей
точкой) используется соотношение (1.1.2). В качестве примеров таких тестов могут
служить тесты SPECint95 и SPECfp95 [5-9].
Все вышеперечисленные показатели не учитывают обмены информацией между
устройствами. Для учёта этих зависимостей вводят наборы типовых задач
Z  Z1 , Z 2 ,..., Z m . Для задачи Z j  Z известно количество выполняемых операций  i (с
учётом операций ввода-вывода и операций обмена информацией) и время выполнения
вычислительных операций t j . Быстродействие вычислительного модуля при решении
типовой задачи будет:

j  j ,
(1.1.9)
tj
Определяются вероятности спроса на типовые задачи в виде
k

j 1
j
1 ,  2 ,...,  k 
 1 , тогда среднее быстродействие вычислительного модуля:
 ср 
1
(1.1.10)
j

j 1  j
Использование соотношения (1.1.10) для однородных ВС может быть использовано
k
в виде
 ср* 
N
,
(1.1.11)
j

j 1  j
где N – количество вычислительных модулей в ВС.
При использовании соотношения (1.1.10) для неоднородных ВС его необходимо
модифицировать, учитывая наличие n типов вычислительных модулей
n
N
 срн  (  k i ) / n ,
(1.1.12)
 ji
i 1
k

j 1
ji
Для использования показателей (1.1.10-1.1.12) существует множество специальных
тестовых наборов Z. Наиболее известным является набор LINPACK [5-9], определяющий
производительность вычислительных модулей при решении систем линейных уравнений.
Естественно, что применимость тестовых наборов Z должна быть обеспечена для
различных архитектур вычислителей, по крайней мере на уровне языков высокого уровня.
Показатель (1.1.7), как нетрудно заметить, в сильной степени зависит от выбора
системы тестов Z. Поэтому в отдельных случаях чтобы уменьшить эту зависимость,
вводят унифицированные операции и операнды. Унифицированным формам данных
может быть выбран байт. В качестве унифицированной операции выбирают, например,
11
операцию
сравнения
данных.
унифицированную, в виде
Все остальные операции выражаются через
Uf
Kf 
, где Uf – рассматриваемая операция, U –
U
унифицированная операция.
Унифицированное быстродействие для j–ого теста определяется как:
V
 ун j  j ,
tj
(1.1.13)
где V j – количество унифицированных операций в тесте Z j  Z , t j – время решения
задачи Z j , которое учитывает как время решения самой задачи, так и накладные расходы
(на преобразование, ввод-вывод информации) и т.д.
Среднее унифицированное быстродействие определим
 ун 
1
j

j 1  ун j
m
,
(1.1.14)
где  j – вероятность вызова Z j типовой задачи.
Для однородных систем среднее унифицированное быстродействие определится
как
N
 ун*  m
,
(1.1.15)
j

j 1
ун j
где N – количество вычислительных модулей в однородной ВС.
Неоднородные ВС, имеют в своём составе n типов вычислительных модулей,
поэтому среднее унифицированное быстродействие представится в виде
n
N
 унн  (  n i ) / n ,
(1.1.16)
i 1
j

ji 1
i
унi
При оценке быстродействия ВС все вышеприведенные показатели могут служить
основой для получения соответствующих характеристик производительности ВС, хотя
принципиальным вопросом здесь является выбор соответствующих тестов. Существует
способ использования пиковой производительности для определения составной
теоретической производительности ВС, который характеризует зависимость от тактовой
частоты, набора функциональных устройств, разрядной сетки и др., хотя совершенно не
учитывает взаимодействие структур решаемой задачи и ВС. Для получения реальные
оценки производительности осуществляются с помощью создания специальных тестовых
наборов. К настоящему моменту наметились три пути создания тестовых наборов:
1) тесты, разработанные фирмами-изготовителями ВС специально для отработки
качества выпускаемой продукции, которые для широкого круга пользователей не
применимы,
2) тесты, разработанные фирмами-изготовителями ВС для широкого круга
пользователей, которые применимы в большинстве случаев и дают хорошие результаты. К
таким пакетам относятся пакеты Linpack, пакеты группы производителей SPEC, TPC и
др. [5-9]. Так, например, пакеты Linpack используются при ежегодном формировании
списка TOP 500, в котором определены 500 самых быстродействующих ВС. Этот список
можно найти в Internet под указанным именем [7].
12
3) третья группа тестов создаётся, как правило, пользователями, и учитывают
внутренние условия применения ВС.
Ёмкость памяти ВС, несомненно, является одной из основных характеристик ВС
и существенно влияет на быстродействие ВС, а также на её другие важные параметры.
Представляют интерес единицы измерения ёмкости памяти ВС и порядок величин, с
которыми оперирует современная вычислительная техника. Ниже приведены единицы
измерения ёмкости памяти ВС и порядок величин, с которыми оперирует современная
вычислительная техника (в круглых скобках приведены английские сокращения):
1 Килобит (KiloBit) = 1 Кбит (KBit) = 1024 бит (Bit) = 210 бит (Bit);
1 Килобайт (KiloByte) = 1 Кбайт (KByte) = 1024 байт (Byte) = 210 байт (Byte);
1 Мегабит (MegaBit) = 1 Мбит = 1024 Кбит = 220 бит;
1 Мегабайт (MegaByte) = 1 Мбайт (Mbyte) = 1024 Кбайт (Кbyte) = 220 байт (byte);
1 Гигабит (GigaBit) = 1 Гбит (GBit) = 1024 Мбит(МBit) = 230 бит (Bit);
1 Гигабайт (GigaByte) = 1 Гбайт (Gbyte) = 1024 Мбайт (Мbyte) = 230 байт (Byte);
1 Терабит (TeraBit) = 1 Тбит (TBit) = 1024 Гбит (GBit) = 240 бит (Bit) ;
1 Терабайт (TeraByte) = 1 Тбайт (TByte) = 1024 Гбайт (GByte) = 240 байт (Byte);
1 Петабит (PetaBit) = 1 Пбит (PBit) = 1024 Тбит (TBit) = 250 бит (Bit);
1 Петабайт (PetaByte) = 1 Пбайт (PByte) = 1024 Тбайт (TByte) = 250 байт (Byte).
Быстродействие памяти характеризуется так же скоростью обмена информацией
между памятью и другими устройствами вычислителя. В качестве единицы измерения
этой величины используется:
1 бод (boud) = 1 бит/сек (bit per second);
1 Килобод (Kiloboud) = 1 Кбод (Kboud) = 103 бод (boud);
1 Мегабод (Megaboud) = 1 Мбод (Mboud) = 106 бод;
1 Гигабод (Gigaboud) = 1 Гбод (Gboud) =109 бод;
1 byte/s = 1 байт/сек;
1 Килобайт/сек (Кilobyte/s) =1 Кбайт/сек ( Кbyte/s) = 103 байт/сек;
1 Мегабайт/сек (Мegabyte/s) = 1 Мбайт/сек(Мbyte/s) ) = 106 байт/сек.
1.1.1. Вопросы к разделу 1.1.
1. Чем отличается пиковая нагрузка ЭВМ от пиковой нагрузки ВС ?
2. В чём особенность унифицированного быстродействия ?
3. Какие особенности перехода от оценок быстродействия для ЭВМ к оценкам
быстродействия для ВС ?
4. Почему для оценок быстродействия используется система тестов ?
5. Чем отличается оценка быстродействия для однородных систем от оценки
быстродействия для неоднородных систем ?
6. Какие типы тестов существуют ?
7. Какие принципы положены в формирование единиц измерения параметров ВС ?
1.2. Понятие о современных вычислительных системах
Повышение быстродействия вычислений в случае необходимости в эпоху
отсутствия компьютеров осуществлялся за счёт увеличения коллектива вычислителей
(людей, занятых вычислениями). В этом коллективе существовала определённая
технология проведения вычислений, которая, в конечном счёте, позволяла производить
необходимые вычисления. Как показала практика, организация вычислений в
современных ВС во многом копирует опыт, накопленный коллективами вычислителей. В
связи с этим, целесообразно при формулировании исходных определений для ВС
использовать понятия, выработанные при выполнении соответствующих работ
человеческими коллективами вычислителей. Иными словами, можно сказать, что
13
сущность ВС составляет коллектив аппаратно-программных вычислителей, акцентируя
внимание на методах взаимодействия между вычислителями в этих коллективах. В
дальнейшем, при изложении материала вычислитель назван вычислительным модулем
(ВМ), который подразумевает использование процессора или ЭВМ. В литературе вместо
использования термина «вычислительный модуль» можно встретить термины «элементарный процессор», «элементарная машина» и др. Кроме того, архитектура
процессоров
всё
время
совершенствуется
–
появляются
транспьютерные,
мультискалярные, мультитредовые, и т. д. процессоры. В тех случаях, когда это
необходимо, будут делаться необходимые разъяснения и ссылки. В настоящее время
разница между понятиями процессор или ЭВМ достаточно условна. В дальнейшем, под
ЭВМ будем понимать процессор, оснащённый собственной операционной системой и
периферийными устройствами. Связи между процессорами или ЭВМ осуществляются с
помощью сетей связи, которые, в общем случае, представляют собой сосредоточенные
или распределённые коммутаторы с шинами связи. Наиболее удачной была шина PCI,
разработанная в 1991 году фирмой Intel. При рассмотрении проблемы оптимизации
структуры ВС надо иметь в виду , что при выборе графа в качестве математической
модели ВС одно ребро на графе, который описывает структуру ВС, физически может
соответствовать коммутируемой
шине, содержащей большое количество
дополнительного дорогостоящего оборудования. Поэтому всякое упрощение структуры
вычислительной сети, при прочих равных условиях, уменьшает её стоимость. Это
обстоятельство порождает на мировом рынке всё новые конфигурации вычислительных
сетей, имеющих определённые достоинства и недостатки в зависимости от
предъявляемых к ним требований. Некоторые из них будут рассмотрены ниже.
Определение 1.2.1. Система, представленная множеством описаний W={K,A}, где
K – описание конструкций ВС, А – описание алгоритма работы множества
вычислительных модулей, называется вычислительной. Описание К составляет
множества значений {M,S}, где М – множество базовых вычислительных устройств
{mi}, i=0, ... , N-1, где под базовыми вычислительными устройствами понимаются ЭВМ,
процессоры, блоки памяти, внешние устройства. S – сеть связей между множествами
элементов базиса.
В конструкцию К должны быть заложены следующие принципы:
а) параллелизм при обработке информации, т.е. организация вычислений
одновременно на множестве вычислительных модулей М с организацией в случае
необходимости обмена данными через сеть S;
б) адаптация конфигурации сети S к решаемой задаче. Алгоритм А обеспечивает
наряду с требуемой обработкой управление одновременной работой определённым
множеством ВМ и необходимым обменом данными между ними.
Изучаемый здесь курс вычислительных систем основывается, в основном, на
теории графов, поэтому напомним несколько определений из этой теории, которые в
дальнейшем будут часто использоваться [12].
Определение 1.2.2. Графы изоморфны, если отличаются только нумерацией
вершин.
Определение 1.2.3. Графы гомоморфные, если второй получен из первого заменой
нескольких вершин графа одной с сохранением оставшихся связей.
Определение 1.2.4. Графы гомеоморфные, если второй получен из первого
разбиением его рёбер (p,q) на (p,r) и (r,q), где r – новая вершна.
14
Определение 1.2.5. Граф регулярен, если степени вершин одинаковы.
Определение 1.2.6. Граф F называется частью графа G, F G, если множество
его вершин V(F) содержится в множестве V(G), а множество рёбер R(F) – в множеств
рёбер R(G).
Определение 1.2.7. Часть графа F G называется суграфом, если множество его
вершин V(F) = V(G).
Определение 1.2.8. Часть графа F G называется подграфом, если множество
его вершин V(F) содержится в множестве вершин V(G), а множество рёбер связывает
только вершины V(G).
Структура вычислительных систем представляется в виде графа GS=(М,S), каждой
вершине которого поставлены в соответствие вычислительные модули mi , i = 0, … , N-1,
а ребра sj,k  S – связи между ними, j,k  {0, … ,N-1}. Набор связей j,k зависит от
конфигурации сети S.
Для возможности оценки времени, затрачиваемого на обмен информацией между
вычислительными модулями, а также других характеристик, вводятся понятия: регулярная
вычислительная система, диаметр и средний диаметр вычислительной системы.
Определение 1.2.9. Регулярная вычислительная система представляется
неориентированным графом, в котором все вершины графа имеют одинаковую степень
вершин графа, где под степенью вершины понимается количество рёбер, примыкающих к
вершине графа.
Пример графа регулярной вычислительной системы представлен на рисунке 1.2.1.
Определение 1.2.10. Диаметр d – это максимальное расстояние, определяемое как
d = max{ri,j}, i,j {0,…,N-1},
где ri,j – расстояние между вершинами i, j графа рассматриваемой ВС.
Расстояние ri,j есть минимальная длина простой цепи между вершинами i, j, где
длина измеряется в количестве ребер между вершинами i, j.
Например, на рисунке 1.2.1 длины между вершинами (0,5) есть 3 ((0,1),(1,2),(2,5)),
2 ((0,1),(1,5)), 2 ((0,4),(4,5)), 3 ((0,3),(3,4),(4,5)), 3 ((0,3),(3,6),(6,5)), 2 ((0,6,),(6,5)) и др.,
длина которых больше 3-х. Следовательно, расстояние ri,j равно 2. При рассмотрении всех
возможных расстояний определяется d=2.
7
1
6
2
5
3
4
Рисунок 1.2.1. Пример графа регулярной вычислительной системы
Определение 1.2.11.
определяется как
Средний
диаметр
d
 pn
i pi

pi
di = 
N 1
di




для i-й выделенной вершины
(1.2.1)
15
где pi – расстояние от текущей до i-й выделенной вершины, n pi – число вершин,
находящихся на расстоянии p i от выделенной.
Определение 1.2.12. Средний диаметр для графа вычислительной системы
определяется в виде:
N 1
d
d=
i
i=0
N
Примечание: Для регулярной вычислительной системы d i  d .
Сеть S должна обеспечивать в каждый момент времени, требуемый обмен данными
между вычислительными модулями. Наиболее подходящей для этой цели является сеть по
полному графу, т.е. связь каждого вычислительного модуля с каждым. Построение такой
сети для большого количества вычислительных модулей, содержащихся в современных
ВС, является сложной и дорогостоящей процедурой. В связи с чем, разрабатываются
различные типы и конфигурации сетей, в которых обеспечиваются связи в зависимости
от различных требований. Очевидно, что в таких сетях, как правило, возникает
необходимость транзитной передачи информации с помощью вычислительных модулей,
попадающих в контур передачи информации. Такие передачи, естественно, требуют
дополнительных затрат времени, в связи с чем возникает задача минимизации этих затрат
c помощью выбора конструкций тех или иных разновидностей сетей с учетом структуры
решаемых задач. Вследствие этого проблему выбора графа межмодульных связей
необходимо рассматривать в нескольких аспектах:
- минимизация времени выполнения межмодульных обменов;
- максимизация числа одновременно выполняемых обменов;
- максимальная сохранность связности при выходах из строя ВМ и линий.
Таким образом, в качестве критериев выбора графа логично выбрать диаметр и
средний диаметр графа. Диаметр графа определяет максимально необходимое число
транзитных передач, а средний диаметр – среднюю длину транзитного пути. В качестве
показателя, оценивающего вероятность существования межмодульных связей в графе
(при заданных значениях коэффициентов готовности ВМ и линий, компоненты связности,
включающей не менее 0, 1, 2, …, N-1 вершин, где N – количество вычислительных
модулей в системе), используется вектор-функция структурной живучести графа. При
определении данного показателя необходимо произвести достаточно сложные
вычисления. По результатам моделирования оказалось, что минимизация обоих диаметров
является необходимым условием максимизации координат вектор-функции структурной
живучести графа. Поэтому в качестве критерия выбираются диаметр и средний диаметр.
1.2.1 Вопросы к разделу 1.2.
1.
2.
3.
4.
5.
Какие параметры используются при определении ВС?
С какой целью вводится параметр диаметр системы?
В чём сущность параметра средний диаметр системы?
Почему возникает необходимость транзитной передачи информации?
В чём сложность использования конфигурации сети по полному графу?
1.3. Структура современных вычислительных систем
Рассмотрим структуры вычислительных систем по мере усложнения сетей связей
между процессорами. Прообразами современных ВС были вычислительные системы с
простыми коммутаторами с временным разделением, которые называют общими шинами
16
или шинными структурами (см. рисунок 1.3.1) [2]. Шинные структуры наряду с рядом
преимуществ, таких как небольшой объём оборудования, достаточно высокая надёжность,
имеют ряд существенных недостатков. К ним относится особенности, связанные с
методом организации обмена, поэтому принципиально неустранимые:
- одновременная работа только одного передающего устройства,
- наличие арбитра шины, активизирующего в определённые моменты времени
устройства, и требующего для этого определённое время,
- необходимость синхронизации сигналов «запрос-ответ», которая осуществляется
за счёт времени работы шины, и др.
В шинах типа Fastbus, IEEE 960, VME и Futurebus+, IEEE 896.x применены ряд
усовершенствований, позволяющих ускорять процессы обмена, хотя вопрос об
использовании шин в быстродействующих вычислительных системах остаётся открытым.
1.3.1. Схема обмена с помощью структуры «Общая шина»
Схема обмена с помощью структуры «Общая шина» представлена на рисунке
1.3.1 в виде неориентированного графа.
Рисунок 1.3.1. Реализация обмена через общую шину. Вершина графа обозначает
вычислительный модуль, жирная линия – общая шина
Данные от вычислителя поступают в общую шину и в соответствии с
алгоритмом А могут поступать на один из оставшихся вычислителей.
Определение 1.3.1. Структура вычислительной системы типа «Общая шина»
описывается графом GS =(М,S*), где М – множество вычислительных модулей,
определяемых вершинами графа, М ={mi}, {i} ={ 0, … , N-1}, N  3, а S* состоит в
каждый момент времени tk  {t1, … , tk*} из одного ребра sqj, где q, j  { 0, … , N-1}, q≠j,
q<j, а множество времён {t1, … ,tk*} определяет моменты реконфигурации сети S*.
Как правило, интервал времени tk, в течении которого существует определённая
конфигурация сети связи, определяется операционной системой, управляющей
рассматриваемой коммуникационной средой в соответствии с запросами решаемых задач.
На пути развития вычислительной техники появились структуры, которые в
дальнейшем явились прообразами современных ВС. К ним относятся структуры типа
«линейка» и «кольцо».
1.3.2. Схема обмена с помощью структуры «Линейка»
Схема обмена
с помощью структуры
неориентированного графа на рисунке 1.3.2.
«линейка»
представлена
в
виде
•••
Рисунок 1.3.2. Реализация обмена с помощью структуры «Линейка». Вершина графа
обозначает вычислительный модуль. Многоточие обозначает, что опущены ВМ и
связи между ними
17
Каждый вычислительный модуль, кроме первого и последнего, связан с
соседним. Передача данных, в случае необходимости, осуществляется транзитом через
другие вычислители. Недостатком рассматриваемой структуры является малая
надёжность – отказ вычислителя или связи вызывает отказ «линейки». Достоинством
является простота и относительно малая стоимость её изготовления.
Определение 1.3.2. Структура вычислительной системы типа «Линейка»
описывается графом GS =(М,S*), где М – множество вычислительных модулей,
определяемых вершинами графа, М ={mi}, {i} ={ 0, … , N-1}, N  2, а S* состоит из
множества рёбер sq, q+1 , q {0,1, … , N-2}.
1.3.3. Вычислительная система, имеющая структуру типа «Кольцо»
Вычислительная система, имеющая структуру типа «кольцо» представлена на
рисунке 1.3.3.
Каждый вычислительный модуль связан с соседним. «Кольцо» имеет
преимущество перед структурой типа «Линейка», так как первый вычислительный
модуль непосредственно связан с последним.
•••
Рисунок 1.3.3. Схема обмена с помощью структуры типа «Кольцо».
Определение 1.3.3. Структура вычислительной системы типа «Кольцо»
описывается графом GS =(М,S*), где М – множество вычислительных модулей,
определяемых вершинами графа, М ={mi}, {i}={0, … , N-1}, N  2, а S* состоит из
множества рёбер sq, (q+1)mod(N), q  {i}.
Операция (q+1)mod(N) означает остаток от деления по модулю N, т.е. при q=N-1
образуется ребро, связывающее 0 и N-1 вычислители.
1.3.4. Схема обмена с помощью структуры типа «Решётка»
Схема обмена с помощью структуры типа «Решётка» представлена в виде
неориентированного графа на рисунке 1.3.4.
По сравнению с «кольцом» и «линейкой» рассматриваемая структура имеет ряд
преимуществ, в частности, много альтернативных путей обхода при обмене данными
между вычислителями, что существенно увеличивает надёжность рассматриваемой
структуры.
Определение 1.3.4. Структура вычислительной системы типа «Решётка»
описывается графом GS =(М,S*), где М – множество вычислительных модулей,
определяемых вершинами графа, М ={mi}, {i} ={0, … , N-1}, N  4, а S* состоит из
множества рёбер sj, k , j {0,1, … ,Y-1}, k {0,1, … , L-1}, и L*Y=N. Ребро проводится
между вершинами, определяемыми декартовыми произведениями [j]  [k]. Две
вершины соединяются ребром, если декартовы произведения отличаются друг от
друга на 1 по координате j или k, соответственно.
На рисунке 1.3.4 анализируемый граф помещён в систему координат j, k. Значения,
определяемые индексом k, откладываются по оси k, индексом j – по оси j. Определение
1.3.4, таким образом, задаёт решётку в системе координат j, k. Пусть, например, задана
решётка 3  4. Тогда образуются декартовы произведения:
18
[0]  [0], [0]  [1], [0]  [2], [0]  [3],
[1]  [0], [1]  [1], [1]  [2], [1]  [3],
[2]  [0], [2]  [1], [2]  [2], [2]  [3]
и, соответственно, образуются рёбра – при k=0, значения j при этом, будут: (0,1),
(1,2); при k=1, значения j при этом, будут: (1,2), (1,1) и т. д.
Рисунок 1.3.4. Реализация обмена с помощью структуры типа «Решётка»
1.3.5. Схема обмена с помощью структуры типа «Двумерный тор»
Схема обмена с помощью структуры типа «Двумерный тор» представлена в виде
неориентированного графа на рисунке 1.3.5. «Двумерный тор» имеет преимущество перед
структурой типа «решётка», так как некоторые граничные ВМ, а возможно и все,
непосредственно связаны друг с другом. Под граничными вычислительными модулями
понимаются ВМ, имеющие максимальную координату по одной из осей.
Рисунок 1.3.5. Реализация обмена с помощью структуры типа «Двумерный тор»
Определение 1.3.5. Структура вычислительной системы типа «Двумерный тор»
описывается графом GS =(М,S*), где М – множество вычислительных модулей,
определяемых вершинами графа, М ={mi}, i = 0, … , N-1, N  5, а S* состоит из
множества рёбер s к, j , k {0,1, … , L-1}, j {0,1, … ,Y-1} и L*Y=N. Ребро проводится
между вершинами, определяемыми декартовыми произведениями [j]  [k]. Две вершины
соединяются ребром, если их декартовы произведения отличаются друг от друга на 1
или на L-1 по координате L или – на 1 или на Y-1 по координате Y соответственно.
Примечание. К обобщённому двумерному тору (см. рисунок 1.3.5) относятся также
и ВС, содержащие не все рёбра, имеющие индексы j=Y-1или k=L-1.
19
На рисунке 1.3.5 анализируемый граф помещён в систему координат L,Y. Значения,
определяемые индексом k, откладываются по оси L, индексом j – по оси Y.
Определение 1.3.5, таким образом, задаёт двумерный тор в системе координат L,Y.
1.3.6. Схема обмена с помощью структуры типа «n-мерный двоичный
гиперкуб» или «nD-куб»
Схема обмена с помощью структуры типа «n-мерный двоичный гиперкуб» или
«nD-куб» представлена в виде неориентированного графа на рисунке 1.3.6. Главная
причина выбора данных структур – это простота определения трасс передачи данных.
Различают n-мерный двоичный (булев) гиперкуб и обобщенный гиперкуб.
Определение 1.3.6. Структура вычислительной системы типа «n-мерный
двоичный гиперкуб» или «nD-куб» описывается графом GS =(М, S*), где М – множество
вычислительных модулей, определяемых вершинами графа, М ={mi}, i = 0, … , N-1, N=2n .
n-мерный булев куб задается как декартово произведение n множеств {0,1}. S* состоит
из множества рёбер sv,y, таких, что декартовы произведения v и y, отличаются на
единицу.
Y
Z
y
X
X
Рисунок 1.3.6. Пример представления схем булевых кубов различных размерностей:
а)размерность – два, б) размерность – три, в) размерность – четыре
Недостаток таких графов – необходимо, чтобы каждая вершина имела степень n
(число вершин – 2n). Но существует способ упрощения их построения: вершины
представляются как гомоморфные образы простых циклов с n вершинами. Например,
каждая вершина имеет 3 ребра, два из которых используются для образования цикла и
третье – ребро n-мерного куба. На рисунке 1.3.7 показан пример построения такого графа.
Рисунок 1.3.7. Трехмерный куб (каждая вершина – это цикл длины 3)
20
1.3.7. Реализация обмена с помощью структуры типа «Обобщенный nD-куб»
Реализация обмена с помощью структуры типа «Обобщенный nD- куб»
представлена на рисунке 1.3.8.
Рисунок 1.3.8. Схема представления обобщенного 3-х мерного гиперкуба 2х4х3
Определение 1.3.7. Структура вычислительной системы типа «Обобщенный
nD-куб» описывается графом GS =(М, S*), где М – множество вычислительных
n
модулей, определяемых вершинами графа, М ={mi}, i = 0, … , N-1, N  П ( N j ) . По
j 1
каждой координате j, j=1,…,n вводятся точки NJ={0,1, ... , Nj-1}, где Nj – размерность
куба по координате j. Множество вершин графа ВС определяется декартовыми
произведениями [N1]  [N2]  …  [Nn], |N1|·|N2|·…·|Nn|=N. Две вершины соединяются
ребром, если декартовы произведения, определяющие эти вершины, отличаются друг от
друга на 1.
Например, для 3-х мерного обобщённого куба 2х4х3 образуются точки по
координатам x, y, z соответственно (0,1), (0,1,2,3), (0,1,2) и соответствующие декартовы
произведения:
(0,0,0), (0,1,0), (0,2,0), (0,3,0), (1,0,0), (1,1,0), (1,2,0), (1,3,0),
(0,0,1), (0,1,1), (0,2,1), (0,3,1), (1,0,1), (1,1,1), (1,2,1), (1,3,1),
(0,0,2), (0,1,2), (0,2,2), (0,3,2), (1,0,2), (1,1,2), (1,2,2), (1,3,2).
Ребра проводятся между вершинами (0,0,0) и (0,0,1), (0,1,0), (1,0,0). Вершина (0,0,1)
соединяется с вершинами (0,0,0), (1,0,1), (0,1,1), (0,0,2) и т.д. Пример представления этой
структуры показан на рисунке 1.3.8.
1.3.8. Структура ВС типа «N-мерный обобщённый тор»
На основе кубических структур ВС введены торы (для одномерного случая –
кольцевые структуры). N-мерный обобщённый тор образуется из обобщенных n-мерных
кубов построением ребер между отдельными или всеми вершинами, прилегающими к
граничным плоскостям. Так, если ВС построена из обобщенных 2D кубов (3х3), то ребра
могут быть проведены, как показано на рисунке 1.3.9(а). Степень вершины равна 4. На
рисунке 1.3.9(б) показано построение трёхмерного тора из обобщенного 3D куба (2x3x2)
со степенью вершины равной 4.
21
Определение 1.3.8. Структура вычислительной системы типа «обобщенный
nD-тор» описывается графом GS =(М, S*), где М – множество вычислительных
n
модулей, определяемых вершинами графа, М ={mi}, i = 0, … , N-1, N  П ( N j ) . По
j 1
каждой координате j, j=1,…,n вводятся точки NJ={ 0,1, ... , Nj-1}, где Nj – размерность
куба по координате j. Множество вершин графа ВС определяется декартовым
произведением [N1]  [N2]  …  [Nn], |N1|·|N2|·…·|Nn|=N. Множество рёбер S*
строится следующим образом: две вершины соединяются ребром, если декартовы
произведения отличаются друг от друга на 1 или на Nj-1 только по координате Nj ,
j {1,…,n } соответственно.
y
z
y
x
x
Рисунок 1.3.9 ВС типа двумерный тор (а) и трёхмерный тор (б)
С помощью дополнительных связей, выделенных на рисунке 1.3.9 жирными
линиями, из 2D-куба построена ВС типа двумерный тор (а), а обобщенный 3D-куб
переведен в ВС типа трехмерный тор (б).
Примечание. К обобщённому n-мерному тору относятся также и ВС, содержащие
не все рёбра, отстоящие на расстоянии Nj-1 по координате j.
1.3.9. Структура ВС с сетью типа «Циркулянт»
В настоящее время в индустрии ВС получили широкое распространение сети
связей типа циркулянтных, которые относятся к классу регулярных сетей связи. Эти
структуры традиционно представляются Dn-графами, каждый из которых описывается в
виде:
Dn=G (N,q1,…,qn),
(1.3.1)
где N – число вершин в графе, вершины нумеруются от 0 до N-1, а q1,…,qn удовлетворяет
условиям:
0<q1<…<qn≤(N+1)/2,
(1.3.2)
где q1,…, qn – множество образующих чисел таких, что множество {q1,…,qn} имеет
наибольший общий делитель, равный 1.
Вершина i соединяется ребрами с вершинами
22
(i  q1 )(mod N ),..., (i  qn )(mod N ).
(1.3.3)
Функция d (mod) N определяет остаток от деления нацело. Например, 3 (mod) 5=3.
Определение 1.3.9. Структура вычислительной системы типа «Циркулянт»
описывается графом GS =(М,S*), где М – множество вычислительных модулей,
определяемых вершинами графа, М ={mi}, i = 0, … , N-1. Построение сети S*
удовлетворяет условиям (1.3.1), (1.3.2) и соотношениям (1.3.3).
Пример циркулянта, представленной в виде двумерной матрицы или хордового
кольца для циркулянта {7,1,3} показан на рисунке 1.3.10а и на рисунке 1.3.10б
соответственно.
Рисунок 1.3.10. Пример циркулянта {7,1,3}, изображенной в виде двумерной матрицы (а)
и хордового кольца (б)
1.3.10. Вычислительная система «Максимальный обхват»
Вычислительная система «Максимальный обхват» имеет граф связей с
максимальным обхватом. Построение графа с максимальным обхватом осуществляется
следующим образом. Обхват графа – это длина его простого кратчайшего цикла. Пусть v –
это степень вершины графа, i – номер яруса. Данный вид графов строится по следующим
правилам:
1) произвольно берется начальная вершина;
2) каждая следующая вершина i-го яруса связывается с одной вершиной (i-1)-го
яруса и с (v-1) вершинами яруса (i+1);
3) максимально возможное число вершин i-го яруса равно v(v-1)i-1;
4) выбранный критерий выполняется, быть может за исключением последнего,
если количество вершин на всех ярусах максимально: N=(v(v-1)d-2)/(v-2);
5) свободные связи вершин последнего яруса соединяются между собой либо на
последнем ярусе находится N-(v(v-1)d-1-2)/(v-2) вершин и соединяются свободные ребра
двух последних ярусов. В настоящее время единственный известный способ построения
таких графов – это полный перебор возможных вариантов.
Определение 1.3.10. Структура вычислительной системы типа «Максимальный
обхват» описывается графом GS =(М, S*), где М – множество вычислительных
модулей, определяемых вершинами графа, М ={mi}, i = 0, … , N-1. Построение сети S*
выполняется согласно вышеприведенным пяти правилам.
23
1.3.11. Вычислительные системы со структурой сетей типа «Симметричные
графы»
Для описания межмодульных связей также используют симметричные графы. Их
главное преимущество перед рассмотренными графами заключается в более компактном и
удобном способе их задания.
Пусть V – множество вершин графа, состоящее из N элементов. Они нумеруются
числами 0, 1, …, N-1. Разобьем множество V на s классов эквивалентности. Распределение
вершин по классам осуществляется по следующей формуле:
Vi  i  ks mod N , i  0, s  1, k  1,2,...
(1.3.4)
Каждому классу Vi поставим в соответствие множество положительных целых
чисел,
M i  m[i, k ], k  1, ri
(1.3.5)
ri задает количество ребер вершины класса Vi. При помощи чисел Mi задаются
связи – какие две вершины необходимо соединить ребром:
(1.3.6)
b; b  m[i, j]mod N , b V , j  1, ri .
Определение 1.3.11. Структура вычислительной системы типа «Симметричный
граф» описывается симметричным графом GS =(М, S*), где М – множество
вычислительных модулей, , определяемых вершинами графа, М ={mi}, i = 0, … , N-1.
Построение сети S* выполняется согласно вышеприведенным соотношениям (1.3.4),
(1.3.5), (1.3.6).
Например, для N=12, s=3 и М0={1,2,3}, M1={2,4}, M2={5}, тогда классы
определятся как
V0={0,3,6,9}, V1={1,4,7,10}, V2={2,5,8,11}
Множество ребер составят:
(0,1) (3,4) (6,7) (9,10)
(0;2) (3;5) (6;8) (9;11)
(0;3) (3;6) (6;9) (9;0)
(1;3)
(1;5)
(4;6)
(4;8)
(7;9) (10;0)
(7;11) (10;2)
(2;7) (5;10) (8;1) (11;4)
На рисунке 1.3.11. представлена ВС с симметричным графом.
Рисунок 1.3.11. Симметричный граф, N=12, s=3
24
1.3.12. Вычислительные системы с сетью связей типа «Гомоморфные графы»
В качестве сетей связей иногда используют гомоморфные графы, так как процесс
создания ВС хорошо моделируется процессом построения гомоморфных графов.
Пусть дан граф G=(V,E), где V – множество вершин графа, E – множество его
ребер. Выберем во множестве V любые две вершины xi и xj. Построим множество вершин
V1, заменив выбранные вершины xi и xj одной новой вершиной xij. Далее построим
множество ребер E1. Если ребро в E не инцидентно ни одной из вершин xi и xj, то это
ребро просто переносится во множество E1. Если ребро в E инцидентно хотя бы одной из
вершин xi и xj, то ребро в E1 получается из ребра E заменой вершины xi или xj новой
вершиной xij. Говорят, что образованный таким образом граф G1=(V1,E1) получен из
графа G=(V,E) с помощью операции элементарного гомоморфизма. А граф G1 называется
гомоморфным образом графа G. Пример такого преобразования представлен на
рисунке 1.3.12.
xi
xj
xij
Рисунок 1.3.12. Операция элементарного гомоморфизма над графом
Теперь рассмотрим системы, где находят свое применение гомоморфные графы.
При проектировании реальных ВС часто используется блочно-иерархический подход,
заключающийся в декомпозиции объектов и задач с разной степенью детализации их
описания и иерархической подчиненностью этих описаний. Иными словами, на самом
нижнем уровне система представляется совокупностью «базовых» элементов, на
следующем уровне – эти базовые элементы объединяются в более крупные и так далее.
Например, символически это можно представить следующим образом:
ЭВМ  платы  блоки  стойки,
где стрелки показывают процесс усложнения конструкции. При этом один тип
графа межмодульных связей используется для объединения ВМ на плате, а другой тип
графа, вершинам которого соответствуют платы, – для объединения плат в блоки и т.д.
Из практики также известно, что при решении большой задачи активно
взаимодействует только часть машин системы. На основе этих наблюдений можно
разбить систему на части (блоки), внутри которых активно взаимодействующие
вычислительные модули связаны быстродействующим коммутатором, а межблочные
связи – менее быстродействующими коммутаторами, так как обмен данными происходит
не часто. Построенные по такому принципу системы называют блочными. Они являются
примерами систем с гомоморфными графами.
Определение 1.3.16. Структура вычислительной системы типа «Гомоморфный
граф» описывается симметричным графом, определяемых вершинами графа, GS
=(М, S*), где М – множество вычислительных модулей, определяемых вершинами графа,
М ={mi}, i = 0, … , N-1. Связи сети S* соответствуют рёбрам графа, гомоморфному
заданному.
Ниже приведены примеры систем с гомоморфными графами межмодульных
связей.
25
Граф межмодульных связей Tera MTA-1 [13]. Коммуникационная среда этого
суперкомпьютера реализована в виде трехмерного обобщённого тора 2×4×8 и состоит из
64 узлов. Однако узлы имеют всего 4 коммуникационных порта (помимо одного канала
для подключения процессора, или модуля памяти, или процессора ввода-вывода), а не 6,
как требуется для трехмерного тора. Поэтому часть связей прошлось опустить: узлы
имеют связи по координате z и по одной из координат x или y, в зависимости от четности z
(рисунок 1.3.13).
Рисунок 1.3.13. Фрагмент графа межузловых связей
При гомоморфном отображении соседних узлов с четным и нечетным значениями
z можно получить трехмерный тор с меньшим в два раза максимальным значением
координаты z.
Процессор Процессор
+
+
Память
Память
Коммутатор 5х5
...
Коммутатор 5х5
Кольцевой канал
Когерентного
интерфейса SCI
Рисунок 1.3.14. Структура системы SPP 1000
Граф межмодульных связей Convex Exemplar SPP 1000 [14]. Это еще один пример
системы с гомоморфным графом связей, причем здесь наблюдается двойной
гомоморфизм. Рассмотрим подробнее структуру системы SPP 1000 (рисунок 1.3.14).
Во-первых, в данной ВС ВМ компонуется из двух процессоров. Отображение двух
ВМ в одну вершину – это первый гомоморфизм.
Во-вторых, блоки системы для внутренних взаимодействий используют простые
коммутаторы (crossbar) 5×5, которые для этих целей имеют 4 входа и 4 выхода. А пятые
входы и выходы коммутаторов реализуют связь с кольцевым каналом. Этот канал
представляет собой одномерный тор, объединяющий до 16 блоков, и состоящий из 4-х
независимых подканалов («точка-точка»), что обеспечивает наивысшую скорость обмена
26
между блоками и повышает отказоустойчивость канала и системы в целом. Отображение
коммутатора с подключенными к нему ВМ в одну вершину тора – это второй
гомоморфизм.
Структура MBC-100 [15]. Это пример другого построения блочных систем. Здесь
применены следующие архитектурные решения.
Особенностью MBC-100 является разделение информационного обмена и
вычислительных процессов. Первую задачу реализуют транспьютеры (T425 или T805),
вторую – микропроцессоры типа i860. Обеспечивается также достаточный объем
оперативной памяти в каждом ВМ, что позволяет буферизировать поток сообщений и
реализовать асинхронный режим работы ВМ в системе.
В основе построения MBC-100 лежит блочная структура. Структурный модуль
скомпонован из 16 ВМ, связи между которыми имеют матричную организацию
(рисунок 1.3.15).
ВМ
Рисунок 1.3.15. Структурный модуль MBC-100
В матрице 4×4 4 угловых элемента соединяются попарно по диагонали
транспьютерными линками. Благодаря этому максимальная длина пути в структурном
модуле уменьшилась с 6 до 3.
Из оставшихся 12 связей: 4 угловых служат для взаимодействия с внешними
устройствами и 8 – для соединения с другими структурными модулями. Эти связи
позволяют реализовать блочную структуру, то есть объединять структурные модули в
модули следующего уровня. На следующем уровне – базовый вычислительный
модульный блок, состоящий уже из 32-х ВМ (рисунок 1.3.16а). Здесь число свободных
связей равно 16. Следующий уровень – объединение базовых блоков, которое будет
состоять из 64-х ВМ. Здесь число свободных связей тоже равно 16. Дальнейшее
наращивание числа вычислительных модулей можно осуществить, объединяя базовые
блоки через дополнительные транспьютеры – по одному на каждую внешнюю связь
(рисунок 1.3.16б).
27
а)
Дополнительный
транспьютер
Базовый блок
32 ВМ
Базовый блок
32 ВМ
Базовый блок
32 ВМ
Базовый блок
32 ВМ
б)
ВМ
ВМ
Рисунок 1.3.16. Блоки различных уровней MBC-100: а) система из 4-х базовых модулей,
б) схема построения базового блока их 2-х структурных модулей
1.3.13. Вычислительные системы с сетью связей типа «Граф Л(N,v,g)»
Построение графа Л(N,v,g) осуществляется следующим образом: выбирается
некоторый подграф бесконечного планарного графа L(v,g), содержащий N вершин.
Вершины подграфа, имеющие степень меньше, чем v, соединяются рёбрами так, чтобы
степени этих вершин стали равными v. Таким способом из бесконечного планарного
графа L(v,g) можно построить множество графов Л(N,v,g), среди которых выбирается
граф Л(N,v,g) с минимальным числом простых циклов, длина которых отличается от g.
Рассмотрим алгоритм построения бесконечного планарного графа L(v,g) [1,2] более
подробно:
Заданы: степень вершин графа v; обхват графа g; количество ярусов NY, которые
будут построены. Введем переменную NG общего числа вершин графа; матрицу s[i,j]
номеров j-ых вершин на i-ых ярусах графа; матрицу X(i,j) свободных связей j-ых вершин
на i-ых ярусах; матрицу B(i,j) текущих степеней j-ых вершин на i-ых ярусах; матрицу
A(s[i,j], s[p,q]) смежностей вершин; вектор N(i) – число вершин на i-м ярусе. Пусть i –
номер текущего яруса, j – номер текущей вершины на ярусе. Здесь окружность
соответствует ярусу.
1. Исходные значения: обнуляем X(n,m), B(n,m), A(k,k), N(n).
28
2. Выбираем точку на плоскости, представляющую вершину s[0,0] – единственная
вершина нулевого яруса. Полагаем N[0]:=1; NG:=1. s[0,0]:=0.
3. Номер текущего яруса i:=1. Количество вершин на первом ярусе N[1]:=v;
NG:=NG+N[1].
4. Строим первую окружность (ярус) с центром в вершине s[0,0]. Разбиваем ее на v
разных частей v точками. Размещаем в каждой точке вершины s[1,k], k  0, (v  1) . Причем
вершина s[1,k] располагается между s[1,(k-1)mod v] и s[1,(k+1)mod v], то есть вершины
следуют по порядку. Вычисляем s[1,k]:=N[0]+k, k  0, (v  1) .
5. Строим ребра (s[0,0]; s[1,k]), k  0, (v  1) , то есть соединяем центральную
вершину s[0,0] со всеми вершинами первого яруса. Формируем матрицу смежности
A[0,s[1,k]]:=1; A[s[1,k], 0]:=1.
6. Проверяем, построены ли все ярусы: i>NY. Если да, то переходим на шаг 15,
иначе – шаг 7.
7. Вычисляем i:=i+1. Строим i-ю окружность с центром в вершине s[0,0]. Полагаем
j:=0; N[i]:=0.
8. Проверяем, существует ли j-я вершина предыдущего (i-1)-го яруса: j<N[i-1].
Если да, то переходим на шаг 9. Иначе – NG:=NG+N[i] и переход на шаг 15.
9. Вычисляем для вершины s[i-1,j]: степень B[i - 1, j] :
N [ i 1]1
 A[ j, f ] ,
количество
f 0
оставшихся свободных связей X[i-1,j] := v - B[i-1,j]. Вычислим количество вершин,
которые необходимо построить на текущем i-ом ярусе: N[i] := N[i] + X[i-1,j].
10. Вычисляем j := j +1. Переход на шаг 8.
11. Разбиваем i-ю окружность N[i] точками на N[i] равных частей. В каждой точке
размещаем вершины s[i,k], k  0, ( N [i ]  1) . Причем вершины следуют по порядку, то есть
s[i,k] располагается между вершинами s[i,(k-1)mod N[i]] и s[i,(k+1)mod N[i]]. Вычисляем
i 1
s[i, k ] :  N[ f ]  k , k  0, ( N [i ]  1) .
f 0
12. Строим ребра:

 s[i  1, j ];

j 1

s[i,  xi  1, k ] ,
k 0


 s[i  1, j ];


 s[i  1, j ];

j 1

s[i, x(i  1, j )  1   xi  1, k ] ,
k 0

j 1

s[i, 1   xi  1, k ] ,  ,
k 0

j  0, ( N [i  1]  1)
Формируем матрицу смежности:
j 1
j 1




A s[i  1, j ], s[i,  xi  1, k ] : 1, A s[i  1, j ], s[i, 1   xi  1, k ] : 1, ...,
k 0
k 0




j 1


A s[i  1, j ], s[i, x(i  1, j )  1   xi  1, k ] : 1
и
k 0


j 1
j 1




A s[i,  xi  1, k ], s[i  1, j ] : 1, A s[i, 1   xi  1, k ], s[i  1, j ] : 1, ...,
k 0
k 0




j 1


A s[i, x(i  1, j )  1   xi  1, k ], s[i  1, j ] : 1,
j  0, ( N [i  1]  1)
k 0


13. Если при слиянии двух соседних вершин i-го яруса s[i,k] и s[i,(k+1)mod N[i]],
k  0, ( N [i ]  1) образуется простой цикл длины g, то эти вершины сливаются; количество
вершин i-го яруса уменьшается на 1: N[i] := N[i] – 1. Перенумеровываем вершины.
Если проверены все возможные слияния вершин, то переход на шаг 14. Иначе – на
шаг 13.
29
14. Если при соединении двух соседних вершин i-го яруса
s[i,k] и
s[i,(k+1)mod N[i]], k  0, ( N [i ]  1) ребром (s[i,k]; s[i,(k+1)mod N[i]]) образуется простой
цикл длины g, то такое ребро вводится в граф. Если введены все возможные ребра, то
переходим на шаг 6. Иначе – переход на 14.
15. Конец алгоритма.
Схема данного алгоритма представлена на рисунках 1.3.17 и 1.3.18.
На вход алгоритма (процедура PPG (v,g,NY)) подаются параметры v, g и NY. Алгоритм
выдает результат работы в графическом виде – планарный граф L(v,g) с заданным
количеством ярусов NY.
Рассмотрим процедуры, входящие в рассматриваемый алгоритм.
Процедура ODC – основная процедура – определяет длину простого цикла в графе.
Входные данные – пара соседних вершин s[i,k] и s[i,(k+1)mod N[i]]. Выдает она – длину
простого цикла g1, который образуется при слиянии пары этих вершин в одну. Для
определения цикла в графе можно было бы использовать один из широко известных
методов, например, поиск в глубину. Однако подобные алгоритмы имеют большую
вычислительную сложность. Зная закономерность расположения вершин в графе, можно
построить алгоритм значительно проще:
1. Пусть g1:=0; f0:=s[i,j]; fk:=s[i,(k+1)mod N[i]]. SM:=f0 – множество
просмотренных вершин.
2. Проверяем f0=fk? Если да, то переходим на шаг 6. Иначе – шаг 3.
3. Используя матрицу смежности A[f0,k], k  0, ( NG  1) , найдем {fl} – множество
вершин, смежных с f0. Удалим просмотренные вершины: {fl}:={fl}\SM.
4. Определим ярусы {yl}, которым принадлежат вершины из {fl}. Выберем из
множества ярусов {yl} максимальный ярус – y_max и множество вершин {fl}_max,
принадлежащих этому ярусу. Из множества {fl}_max выбираем вершину с минимальным
номером – fmin.
Полагаем: f0:=fmin; SM:=SM+{fmin}; g1:=g1+1. Переходим на шаг 2.
5. Простой цикл пройден. Его длина равна g1. Конец алгоритма.
Остальные процедуры носят вспомогательный характер:
Процедура RV – рисует N[i] вершин на i-ом ярусе графа. Реализуется при помощи
графических средств языка программирования. Также здесь предполагается расчет
порядкового номера вершины в графе на основании ее номера в яруса k и номера яруса i:
i 1
s[i, k ] :  N[ f ]  k ,
k  0, ( N [i ]  1)
f 0
Процедура RR – рисует ребро между заданными вершинами s[i-1,j] и s[i,j1].
Реализуется также при помощи графических средств языка программирования.
Дополнительно необходимо вычислить элементы матрицы смежности, так как введение
ребра влияет на смежность вершин: A(s[i-1,j], s[i,j1]):=1 и A(s[i,j1], s[i-1,j]):=1.
Процедура OSV – определяет степень j-ой вершины (i-1)-яруса. Использует
матрицу смежности A. Выдает матрицу степеней: B[i-1,j]:=B[i-1,j]+A[s[i-1,j],f],
f=0, … , N[i-1]-1.
Процедура Summa – вспомогательная процедура для определения вершин, которые
соединяются ребрами (пункт 12 алгоритма построения бесконечного планарного
j 1
графа L(v,g)). На вход подаются – i, j, X. Процедура выдает результат R:=
 xi  1, k ] .
k 0
Процедуры SV – перерисовывает граф при слиянии двух вершин s[i,k] и
s[i,(k+1)mod N[i]]. Реализуется при помощи графических средств языка
программирования.
30
Процедуры DR – дорисовывает введенные ребра графа, соединяющие вершины
s[i,k] и s[i,(k+1)mod N[i]]. Реализуется при помощи графических средств языка
программирования
PPG (v,g,NY)
Рисование вершины
s[0,0];
N[0]:=1; NG:=1;
i:=1;
N[1]:=v;
NG:=NG+v
RV (i, N[i])
k=0,..,N[i]-1
RR (s[0,k], s[1,k+1])
Б
да
i > NY ?
нет
Return
i:=i+1;
j:=0;
N[i]:=0;
j < N[i-1] ?
нет
да
OSV (i-1,j,A; B)
X[i-1,j]:=v-B[i-1,j];
N[i]:=N[i]+X[i-1,j];
j:=j+1
NG:=NG+N[i]
RV (i, N[i])
j=0,..,N[i-1]-1
А
Summa (j,X,i,R)
x1=0,..,X[i-1,j]
j1:=x1+R
RR (s[i-1,j], s[i,j1],i,j)
Рисунок 1.3.15. Схема алгоритма построения бесконечного планарного графа L(v,g)
31
А
k=0,..,N[i]-1
ODC (s[i,k],
s[i,(k+1)modN[i], g1)
нет
g1=g ?
да
SV (s[i,k],
s[i,(k+1)modN[i])
N[i]:=N[i]-1
Б
k=0,..,N[i]-1
ODC (s[i,k],
s[i,(k+1)modN[i], g1)
нет
(g1+1)=g ?
да
DR (s[i,k],
s[i,(k+1)modN[i])
Рисунок 1.3.18. Продолжение схемы алгоритма построения бесконечного планарного
графа L(v,g)
Пример 1. Рассмотрим построение трёх ярусов бесконечного планарного графа
L(4,5).
Исходные данные: v=4; g=5; NY=3.
1) Обнуляем X(n,m), B(n,m), A(k,k), N(n). Присваиваем v=4; g=5; NY=3.
2) Строим на плоскости вершину s[0,0]=0; N[0]:=1; NG:=1.
3) i:=1 (первый ярус); N[1]:=4; NG:=1.
4) Вершины на первой окружности: s[1,0]=1, s[1,1]=2, s[1,2]=3, s[1,3]=4.
5)Ребра: (s[0,0]; s[1,0]), (s[0,0]; s[1,1]), (s[0,0]; s[1,2]), (s[0,0]; s[1,3]). Построенный
фрагмент графа представлен на рисунке 1.3.19.
1,0
1,3
0,0
1,1
1,2
Рисунок 1.3.19. Один ярус графа L(4,5)
32
Формируем матрицу смежности: A[0,1]:=1, A[0,2]:=1, A[0,3]:=1, A[0,4]:=1.
6) i=1 < 3, переход на шаг 7.
7) i:=2 (второй ярус);
8), 9), 10)
j=0: B[1,0]:=1, X[1,0]:=4-1=3,
N[2]:=0+3=3;
j=1: B[1,1]:=1, X[1,1]:=4-1=3,
N[2]:=3+3=6;
j=2: B[1,2]:=1, X[1,2]:=4-1=3,
N[2]:=6+3=9;
j=3: B[1,3]:=1, X[1,3]:=4-1=3,
N[2]:=9+3=12.
j=4, тогда присваиваем NG:=17 и переход на шаг 15.
11) Вершины на второй окружности расположим еще 12 вершин: s[2,0]=1,
s[2,1]=6, s[2,2]=7, …, s[2,10]=15, s[2,11]=16.
12) Ребра: каждую вершину первого яруса соединяем с тремя вершинами второго
яруса, доводя степени вершин первого яруса до четырёх (рисунок 5.3.20а):
j=0: X[1,0]=3:
(s[1,0]; s[2,0]),
(s[1,0]; s[2,1]),
j=1: X[1,1]=3:
(s[1,1]; s[2,3]),
(s[1,1]; s[2,4]),
j=2: X[1,2]=3:
(s[1,2]; s[2,6]),
(s[1,2]; s[2,7]),
j=3: X[1,3]=3:
(s[1,3]; s[2,9]),
(s[1,3]; s[2,10]),
(s[1,0]; s[2,2]);
(s[1,1]; s[2,5]);
(s[1,2]; s[2,8]);
(s[1,3]; s[2,11]).
13) При слиянии вершин:
(s[2,0]; s[2,1]) – длина простого цикла = 4 < g=5;
(s[2,1]; s[2,2]) – длина простого цикла = 4 < g=5;
………………………………………………...
(s[2,11]; s[2,0]) – длина простого цикла =4 < g=5.
Граф остается без изменений
14) Введем поочередно ребра между соседними вершинами. Простой цикл длины
пять получился при ребрах: (s[2,2]; s[2,3]), (s[2,5]; s[2,6]), (s[2,8]; s[2,9]), (s[2,11]; s[2,0]).
Эти ребра добавляем в граф ( рисунок 1.3.20-б). Переход на шаг 6.
2,1
2,0
2,
11
2,
10
2,1
2,2
1,0
1,3
0,0
2,8
2,
11
2,3
2,
10
2,4
1,1
1,2
2,9
2,0
2,5
1,0
1,3
0,0
2,8
2,7
2,3
2,4
1,1
1,2
2,9
2,6
2,2
2,5
2,6
2,7
а)
б)
Рисунок 1.3.20. Фрагменты строящегося графа L(4,5)
6)
i=2 < 3, переход на шаг 7.
7)
i:=3 (третий ярус); j:=0; N[3]:=0.
8, 9, 10) j=0:
B[2,0]:=2, X[2,0]:= 2,
N[2]:=0+2=2;
33
j=1:
B[2,1]:=1, X[2,1]:= 3, N[2]:=5;
j=2:
B[2,2]:=2, X[2,2]:= 2, N[2]:=7;
j=3:
B[2,3]:=2, X[2,3]:= 2, N[2]:=9;
j=4:
B[2,0]:=1, X[2,4]:= 3, N[2]:=12;
j=5:
B[2,5]:=2, X[2,1]:= 2, N[2]:=14;
j=6:
B[2,6]:=2, X[2,2]:= 2, N[2]:=16;
j=7:
B[2,7]:=1, X[2,3]:= 3, N[2]:=19;
j=8:
B[2,8]:=2, X[2,8]:= 2, N[2]:=21;
j=9:
B[2,9]:=2, X[2,9]:= 2, N[2]:=23;
j=10:
B[2,10]:=1, X[2,10]:= 3, N[2]:=26;
j=11:
B[2,11]:=2, X[2,11]:= 2, N[2]:=28.
j=12, тогда присваиваем NG:=45 и переход на шаг 11.
11) На третьей окружности: расположим еще 28 вершин: s[3,0]=17, s[3,1]=18,
s[3,2]=19, …, s[3,26]=43, s[3,27]=44.
12) Каждую вершину второго яруса соединяем с вершинами третьего яруса, доводя
степени вершин второго яруса до четырёх:
j=0: X[2,0]=3:
(s[2,0]; s[3,0]),
(s[2,0]; s[3,1]);
j=1: X[2,1]=3:
(s[2,1]; s[3,2]),
(s[2,1]; s[3,3]);
(s[2,1]; s[3,4]);
j=2: X[2,2]=3:
(s[2,2]; s[3,5]),
(s[2,2]; s[3,6]);
j=3: X[2,3]=3:
(s[2,3]; s[3,7]),
(s[2,3]; s[3,8]);
j=4: X[2,4]=3:
(s[2,4]; s[3,9]),
(s[2,4]; s[3,10]);
(s[2,4]; s[3,11]);
j=5: X[2,5]=3:
(s[2,5]; s[3,12]),
(s[2,5]; s[3,13]);
j=6: X[2,6]=3:
(s[2,6]; s[3,14]),
(s[2,6]; s[3,15]);
j=7: X[2,7]=3:
(s[2,7]; s[3,16]),
(s[2,7]; s[3,17]);
(s[2,7]; s[3,18]);
j=8: X[2,8]=3:
(s[2,8]; s[3,19]),
(s[2,8]; s[3,20]);
j=9: X[2,9]=3:
(s[2,9]; s[3,21]),
(s[2,9]; s[3,22]);
j=10: X[2,10]=3: (s[2,10]; s[3,23]), (s[2,10]; s[3,24]);
(s[2,10]; s[3,25]);
j=11: X[2,11]=3: (s[2,11]; s[3,26]), (s[2,11]; s[3,27]).
13) При слиянии вершин:
(s[3,0]; s[3,1]) – длина простого цикла = 0 < g=5;
(s[3,1]; s[3,2]) – длина простого цикла = 4 < g=5;
...
(s[3,27]; s[3,0]) – длина простого цикла =3 < g=5.
Все получаемые простые циклы имеют длину 0, 4 или 3. Поэтому граф остается без
изменений.
14)
Введем поочередно ребра между соседними вершинами. Простой цикл
длины 5 получился при ребрах: (s[3,1]; s[3,2]), (s[3,4]; s[3,5]), (s[3,8]; s[3,9]), (s[3,11];
s[3,12]), (s[3,15]; s[3,16]), (s[3,18]; s[3,19]), (s[3,22]; s[3,23]), (s[3,25]; s[3,26]). Эти ребра
добавляем в граф. Они показаны жирными линиями на рисунке 1.3.21. Переход на шаг 6.
6) i=3, т.е требуемое количество ярусов построено. Переход на шаг 15.
15) Конец алгоритма.
34
3,2
3,3
3,4
3,1
3,5
3,0
3,6
3,
27
3,7
2,1
2,0
3,
26
2,2
3,8
2,
11
3,
25
1,0
2,3
3,9
2,
10
3,
24
1,3
0,0
3,
10
2,4
1,1
3,
23
3,
11
1,2
2,9
3,
22
2,5
2,8
3,
12
2,6
2,7
3,
21
3,
20
3,
13
3,
14
3,
19
3,
18
3,
17
3,
16
3,
15
Рисунок 1.3.21. Планарный граф L(4,5) в трех ярусах
В результате построены первые три яруса бесконечного планарного графа L(4,5)
(рисунок 1.3.19).
Пример 2. Рассмотрим теперь построение трёх ярусов бесконечного планарного
графа L(3,4).
Исходные данные: v=3; g=4; NY=3.
Краткие выкладки по построению графа:
N[0]:=1; i:=1; N[1]:=3.
Начальная вершина s[0,0] соединяется ребрами с тремя вершинами первого яруса.
i:=2; j=0, ..., 2:
B[1,0]:=1;
B[1,1]:=1;
B[1,2]:=1;
X[1,0]:=2;
X[1,1]:=2;
X[1,2]:=2;
N[2]:=6. Строится шесть вершин на втором ярусе.
Фрагмент графа представлен на рисунке 5.3.22а.
Здесь при слиянии последовательно вершин (2,1)-(2,2), (2,3)-(2,4) и (2,5), (2,6)
образуются простые циклы длины g1=4=g. N[2]:=3. Граф после слияния вершин и их
перенумерации показан на рисунке 1.3.22б.
2,0
2,0
2,1
2,1
1,0
1,0
0,0
0,0
1,2
2,5
1,2
1,1
2,4
2,3
1,1
2,2
а)
2,2
б)
Рисунок 1.3.22. Фрагменты строящегося графа L(3,4)
i:=3; j=0..2: B[2,0]:=2;
X[2,0]:=1;
B[2,1]:=2;
X[2,1]:=1;
B[2,2]:=2;
X[2,2]:=1; N[3]:=3.
35
Строятся три вершины на третьем ярусе. Вершины второго яруса соединяются
ребрами с вершинами третьего яруса. Фрагмент графа представлен на рисунке 1.3.23а.
Здесь все вершины третьего яруса слились в одну с образованием двух простых циклов
длины пять – рисунок 1.3.23б.
3,0
3,1
3,0
2,0
2,1
2,0
2,1
1,0
1,0
0,0
1,2
0,0
1,1
1,2
1,1
2,2
3,2
а)
2,2
б)
Рисунок 1.3.23. Планарный граф L(3,4) в трех ярусах
Ввиду сложности построения требуемого графа Л(N,v,g), который ищется методом
перебора среди множества создаваемых графов Л(N,v,g), генерируется справочник
заинтересованным производителем ВС, в котором наиболее часто используемые графы
представлены в виде матриц смежности. Пример матрицы смежности графа Л(32,4,6) с
d=4 и dср=2.36 представлен на рисунке 1.3.22.
Рисунок 1.3.24. Матрица смежности для графа Л(32,4,6)
Определение 1.3.17. Структура вычислительной системы типа « Л(N,v,g) граф»
описывается графом GS =(М, S*), где М – множество вычислительных модулей,
определяемых вершинами графа, М ={mi}, i = 0, … , N-1. Связи сети S* соответствуют
рёбра графа Л(N,v,g).
На рисунке 1.3.24 представлена структурная схема вычислительной системы
МИКРОС (есть конфигурации МИКРОС-1, МИКРОС-2 и МИКРОС-Т), созданная на базе
оптимальной сети, представленной графом D2(24, 3, 4). Каждый элемент Вi i=0, … ,23
представляет композицию из локальных коммутаторов и вычислительной части.
36
В23
В0
В1
В22
В2
В21
В3
В20
В4
В19
В5
В18
В17
В6
В16
В7
В15
В8
В14
В9
В13
В12
В10
В11
Рисунок1.3.24. Структура ВС МИКРОС в виде D2(24,3,4) графа
Процессор
оперативная
память
Транспьютер
С
В
Я
З
И
коммуникационная
память
Рисунок 1.3.25. Структура элемента Bi вычислительной системы МИКРОС-Т
На рисунке 1.3.25 в состав элемента Bi входят транспьютер, коммуникационная
память, процессор и оперативная память. Эта структура позволяет управлять
переключением узлов с помощью программ и решать вычислительные задачи. Эта
способность и порождает системы с программируемой структурой, а наличие процессора
и оперативной памяти позволяет организовать вычислительный узел. Такая структура
порождает настраиваемую под класс задач вычислительную сеть. В более простых
случаях вместо транспьютера используется распределённый коммутатор и таким образом
может быть создана вычислительная сеть или с фиксированной, или с программируемой
архитектурой.
1.3.14. Структура вычислительной системы типа «Бинарное дерево T0(n)
глубины n»
Схемы алгоритмов решаемых задач часто имеют структуру графа, относящейся к
классу деревьев, поэтому можно предположить, что такие структуры ВС могут оказаться
наиболее подходящими для решения такого класса задач. Ниже предлагаются к
37
рассмотрению две структуры ВС, получившие реальное воплощение в технических
средствах.
Определение 1.3.18. Структура вычислительной системы типа «Бинарное
дерево T0(n) глубины n» описывается графом GS =(М,S*), где М={mi}, i = 0, … , N-1 –
множество вычислителей, определяемых вершинами графа, N = -1 а сеть S* является
бинарным деревом T0(n) глубины n ( N = -1) содержит n рангов r(r = 0, ... , n-1), причем
в каждом ранге размещается ровно
вершин так, что каждая вершина ранга r
( 0 < r < n-2) соединена со своей парой вершин ранга r+1.
Таким образом, как показано на рисунке 1.3.27, каждая вершина в рангах
от 1, ... , n-2 имеет ровно одно входящее и два исходящих ребра, вершина ранга 0 (корень)
имеет два исходящих ребра и все вершины ранга n-1 (крона) – по одному входящему
ребру.
r=0
r=1
r=n-1
Рисунок 1.3.27. Бинарное дерево T0(n) глубины n
1.3.15. Структура вычислительной системы типа «Мультидерево глубины n и
ширины k T1(n,k)»
Определение 1.3.18. Структура вычислительной системы типа «Мультидерево
глубины n и ширины k T1(n,k)», ( N = k* ) описывается графом GS =(М, S*), где М={mi},
i = 0, … , N-1 – множество вычислительных модулей, определяемых вершинами графа,
N =k*( -1), а сеть S* содержит k двоичных деревьев Т0(n), объединенных с помощью
колец R0 и R1. Корневая вершина хi0 (i = 1, ... , k) каждого из k деревьев соединена ребром с
вершиной zi0 а вершины z10, … , zk0 образуют кольцо R0. Второе кольцо R1 образовано
вершинами листьев всех k деревьев и, следовательно, содержит k*
вершин.
x10
x0k
r=0
r=1
...
z10
R0
...
z0k
...
R1
...
r=n-1
Рисунок 1.3.28. Мультидерево T1(n,k) ( N = k*2n) глубины n и ширины k
На рисунке 1.3.28 представлено мультидерево T1(n,k), ( N = k* ) глубины n и
ширины k. На третьем уровне (r=2) образовано кольцо R0, на последнем – r=n-1
38
уровне образовано кольцо R1. Эти кольца объединяют k деревьев в единую
вычислительную сеть.
Предварительное рассмотрение архитектуры вычислительных систем позволило
сделать заключение, что это – достаточно сложное техническое устройство. Для более
полного понимания архитектуры ВС рассмотрим её, наиболее часто используемые,
основные части: структуры некоторых коммуникационных сред и коммутаторов.
1.3.16
Вопросы к разделу 1.3
1. В чём достоинства и недостатки схем обмена с помощью структур типа
«общая шина», «линейка», «кольцо» ?
2. В чём достоинства и недостатки схем обмена с помощью структур типа
структуры типа «Решётка» и «двумерный тор»?
3. Показать различие в определениях схемы обмена с помощью структур типа
«n-мерный двоичный гиперкуб» и «n-мерный двоичный гипертор».
4. В чём достоинства и недостатки схем обмена с помощью структур типа
«обобщенный nD-тор» и «n-мерный двоичный гипертор».
5. Дайте формальное описание структуры вычислительной системы типа
«Циркулянта».
6. Опишите способ построения структуры вычислительной системы типа
«Максимальный обхват».
7. Как построить структуру вычислительной системы типа «Симметричный граф»?
8. Когда удобно использовать структуру вычислительной системы типа
«Гомоморфный граф»?
9. Особенности построения структуры системы SPP 1000.
10. Особенности блочного построения структуры системы МBC-100.
15. Этапы построения структуры вычислительны системы с сетью связей типа
«Граф Л(N,v,g)»
12. Алгоритм построения бесконечного планарного графа L(v,g).
13. Особенности структуры ВС МИКРОС-Т.
14. Достоинства и недостатки структур ВС типа «деревьев» и «мультидеревьев».
1.4. Коммуникационные среды вычислительных систем
Аппаратно-программная реализация сети S достаточно сложна и дорогостоящая и
носит название коммуникационная среда. К настоящему моменту их разработано
достаточно много, так как постоянно делаются попытки по улучшению характеристик
этих конструкций, уменьшению их стоимости. Описание наиболее известных из них
приводится ниже. Коммуникационная среда состоит из адаптера, коммутаторов и кабелей.
Адаптер (сетевой интерфейсный контролер) осуществляет интерфейс между
вычислителем и рассматриваемой сетью. Коммутатор осуществляет совместно с
маршрутизаторами необходимые соединения в ВС. Кабели используются для
подсоединения
соответствующих
каналов
(линков)
к
требуемым
точкам
коммуникационной среды.
Коммуникационная среда должна удовлетворять следующим требованиям:
- максимальная пропускная способность и минимальные задержек в линиях связи,
- максимальная живучесть и надёжность в случае отказов некоторых компонентов ВС,
- высокая вероятность готовности ВС к исполнению возложенных на неё функций,
- технологичность изготовления ВС и простота её обслуживания.
К
настоящему
моменту
создано
достаточно
большое
количество
коммуникационных сред. В качестве примера рассмотрим более подробно особенности
построения некоторых типичных коммуникационных сред.
39
1.4.1. Коммуникационная среда на основе масштабируемого когерентного
интерфейса SCI
Коммуникационная среда на основе масштабируемого когерентного интерфейса
SCI [19] (SCI – Scalable Coherent Interface, принят как стандарт в 1992 г. –
ANSI/IEEE Std 1596 – 1992). Он обеспечивает достижение высоких скоростей передачи с
малыми задержками, позволяет строить многоблочные системы(масштабируемая
архитектура). SCI совмещает в себе шину и локальную сеть, с помощью механизма
распределенных директорий обеспечивает реализацию когерентности кэш-памяти,
находящейся в узле SCI, которая увеличивает производительность в модели с
распределенной разделяемой памятью, уменьшая затраты на доступ к удаленным данным.
Скорость передачи данных в среднем от 200 Мбайт/с до 1000 Мбайт/с при использовании
медных кабелей на расстояниях десятков метров и с оптоволокном – километров. По
сравнению с традиционными алгоритмами обмена данными в сетях, в SCI межузловые
коммуникации выполняются быстрее из-за отсутствия обращений к программным
уровням – библиотекам времени выполнения и операционной системе. Обмен данными
реализован как часть простой операции загрузки данных процессором. Обращение к
данным, физически находящимся в памяти другого ВМ и которых нет в кэше, приводит к
формированию запроса для получения необходимых данных к удаленному узлу, которые
через несколько микросекунд записываются в локальный кэш, и выполнение программы
продолжается. А в прежний подходе требовалось формирование пакетов на программном
уровне, затем передача их аппаратному обеспечению, так же производился прием, в
результате задержки были в сотни раз больше, чем у SCI. Для совместимости с прежними
подходами у SCI есть возможность передачи пакетов других протоколов. Также большая
пропускная способность SCI обеспечивается использованием простых протоколов типа
RISC. Для соединения узлов с адаптерами SCI используют коммутаторы или же
объединение в кольцо. Обычно каждый узел состоит в двух кольцах (рисунок 1.4.1).
Рисунок 1.4.1. Матрица узлов кластера на основе сети SCI
Этот способ эффективен для работы с динамическим трафиком, но для работы с
большими блоками данных не совсем подходит. Используется протокол передачи данных
с гарантированной доставкой. Протокол SCI включает в себя широкие возможности
управления трафиком, для них необходимо наличие сложного программного обеспечения.
Традиционная область применения SCI – это коммуникационные среды
многопроцессорных систем. Технология SCI используется в системах HP/Convex
Exemplar X-class, в системе связи гиперузлов CTI (Convex Torroidal Interconnect), в
кластерных системы SCALI Computer, системах семейства hpcLine компании Siemens, а
также cc-NUMA сервере Data General и Sequent. Модульные SCI-коммутаторы Dolphin
позволяют строить масштабируемые кластерные решения класса предприятия на
платформах Windows NT/2000/XP, Linux, Solaris, VxWorks, LynuxWorks и NetWare с
использованием стандартизированного оборудования и программного обеспечения
40
1.4.2. Коммуникационная среда на основе технологии Myrinet
Сетевую технологию Myrinet представляет компания Myricom [20]. Кроме
продуктов в стандарте Myrinet и программного обеспечения, она поставляет различным
компаниям компоненты высокоскоростных сетей и пакетной маршрутизации – от
специализированных СБИС до аппаратно-программных комплексов. Технология Myrinet
основана на использовании многопортовых коммутаторов при длинах связей узлов с
портами коммутатора, ограниченных несколькими метрами. Узлы в Myrinet объединяются
с помощью коммутатора (до 128 портов(чаще от 4х до 16)). Максимальная длина линий
связи зависит от конкретной реализации. Линки между узлами и коммутатором образуют
полнодуплексные каналы с пропускной способностью 160 Мбайт/с по каждому
направлению. Пропускные способности адаптеров зависят от длины передаваемых
сообщений в установившемся режиме. Реализация Myrinet для оптоволоконного канала с
использованием конвертеров поддерживает расстояние между узлами до 10 км. Эта
технология поддерживается на различных платформах – Intel, MIPS, PowerPC,
UltraSPARC, Alpha под управлением операционных систем FreeBSD, Linux, UNIX, IRIX,
Windows NT, Solaris, Tru64 VxWorks. Сеть Myrinet, структура которой похожа на
сегменты сети Ethernet, соединенные коммутаторами, может одновременно передавать
несколько пакетов со скоростью чуть меньше 2 Гбит/с.
В отличие от Ethernet и FDDI сетей, которые разделяют общую среду передачи,
совокупная пропускная способность сети Myrinet возрастает с увеличением количества
машин. На сегодняшний день Myrinet чаще всего используют как локальную сеть (LAN)
сравнительно небольшого физического размера (несколько метров). Из-за своей высокой
скорости, малого времени задержки, прямой коммутации и умеренной стоимости, система
Myrinet особенно популярна для объединения компьютеров в кластеры. Myrinet также
выполняет роль системной сети (System Area Network, SAN), объединяя компьютеры в
кластер внутри стойки с более низкой стоимостью, чем Myrinet LAN, но с той же
производительностью. Размер пакетов сети Myrinet жестко не задан. Поэтому, они могут
включать в себя другие типы пакетов. Передача пакетов в коммутаторах происходит при
установлении соединения на время передачи. Для маршрутизации сообщений
используются различные алгоритмы прокладки путей. На физическом уровне линки
Myrinet состоят из 9 проводников: в зависимости от состояния девятого бита
определяется, что передаётся в оставшихся 8 битах – байт данных или управляющая
информация. На каждом линке есть управление потоком и контроль ошибок. Среда
Myrinet обладает, в отличие от других коммуникационных сред, например SCI, простотой
концепции и аппаратной реализации протоколов, а также сравнительно низкой
стоимостью сетевого оборудования. Она содержит ограниченный набор средств
управления трафиком, использующих приливно-отливный буфер, управляющие символы
и таймерные интервалы. Myrinet является открытым стандартом. К программному
обеспечению, которое используется при внедрении Myrinet, относится низкоуровневый
интерфейс программирования GM, MPICH/GM, PVM/GM, стек TCP/IP (распространяется
свободно в исходных текстах), а также коммерческие продукты – MPIPro, Scali MPI
Connect. Ранее до 28 % (июнь 2005) кластерных установок из списка Top500 самых
мощных компьютеров мира были построены с применением Myrinet. Теперь этот
показатель упал до 2 % (2009 год).[7]
Подводя итоги рассмотрению системы Myrinet, отметим её достоинства и
недостатки. Достоинствами системы Myrinet являются: широкое распространение и
высокая надежность; хорошее соотношение цена/производительность.
- малое время задержки;
- полнодуплексные 1,28 + 1,28 Гбит/сек линки и коммутируемые порты;
-управление потоком и контроль ошибок на каждом линке;
41
- интерфейсы хоста выполняют управляющую программу, чтобы напрямую
взаимодействовать с процессами, посылать, принимать и выполнять буферизацию
пакетов, а также осуществлять мониторинг сети.
а)
Адаптер
Mirinet
Адаптер
Mirinet
б)
Адаптер
Mirinet
Коммутатор
Рисунок 1.4.2. Структура вычислительных систем, построенных с использованием
адаптеров и коммутаторов Myrinet: а) Система, образованная прямым соединением
линков адаптеров, б) Система, образованная с применением коммутаторов линков
К недостаткам системы Myrinet следует отнести:
- нестандартное решение, поддерживаемое всего одним производителем;
- сложная структура кабельной проводки при максимуме 256 узлов ;
- ограниченная пропускная способность – не более 2 Гбит/с (стандарт Myri-10G до
10 Гбит/с);
- отсутствие возможности подключения к сетям хранения и глобальным сетям;
- отсутствие систем хранения с поддержкой этой технологии.
1.4.3. Краткая характеристика коммуникационной среды QsNet II
QsNet II – это одна из наиболее производительных коммуникационных сред [21].
При передаче программных пакетов длительностью от 1,5 до 2,5 микросекунд
обеспечивается пропускная способность до 912 Мб/сек и рекордно низкое время задержки
в зависимости от процессора. Архитектура QsNet II поддерживает несколько тысяч
вычислительных узлов, обеспечивая широкий диапазон масштабируемости приложений.
Ввиду высокой стоимости оборудования QsNet, как правило, применяется для построения
особо крупных кластеров терафлопного диапазона на базе операционной системы Linux.
Согласно текущему рейтингу, девяносто процентов суперкомпьютеров используют
операционные системы на базе ядра Linux. Владельцами суперкомпьютеров с
оборудованием QsNet и QsNet II являются крупные суперкомпьютерные центры США:
Национальные Лаборатории Lawrence Livermore, Los Alamos, Pacific Northwest и Sandia.
42
Коммуникационная среда QsNet состоит из адаптеров «шина PCI-линк QsNet» и
коммутаторов. Пара адаптеров может соединяться с помощью коммутатора или напрямую
кабелем «адаптер-адаптер». Структуры систем показаны на рисунке 1.4.6. Адаптер QsNet
модели QM 400, построенной на базе микросхемы Elan 3. Интерфейс с компьютером
обеспечивается с помощью шины PCI 2.1, 64 бита, 66 МГц. Линк QsNet представлен
двумя каналами по 10 бит в обе стороны. Пиковая пропускная способность адаптера
«шина PCI – линк QsNet» – 340 Мбайт/с по каждому каналу. Адаптер QsNet II QM 509/500
на базе микросхемы Elan 4. Интерфейс с компьютером – шина PCI-Х 5.0, 64 бита или 128
бит, 133 МГц. Пропускная способность линка QsNet в этом случае – 900 Мбайт/с. Пиковая
пропускная способность адаптера «шина PCI-линк QsNet» – 1064 Мбайт/с. Параллельное
программирование может быть как MPI для систем с распределенной памятью, так и на
базе Shmem, имеющей программный интерфейс (API) передачи информации
для
удаленного доступа по чтению и записи в разделяемую память для систем с разделяемой
памятью. QsNet обеспечивает надежную доставку сообщений, и на этой базе существуют
протоколы IP и файловая система ElanFS.
Адаптер
QsNet
Адаптер
QsNet
а) Система, образованная прямым соединением линков адаптеров
Адаптер
QsNet
Коммутатор
б) Система, образованная с применением коммутаторов линков QsNet
Рисунок 1.4.3. Структура вычислительных систем, построенных с использованием
адаптеров и коммутаторов QsNet
Кластеры с оборудованием Quadrics не раз занимали лидирующие позиции в
списке суперкомпьютеров мира Тор500. Так в 2004 году, кластер Thunder,
принадлежащий Lawrence Livermore National Laboratory, стал вторым по мощности
суперкомпьютером в мире, показав производительность в 19,94 TFlops (87% от пиковой).
Подводя итоги рассмотрения коммуникационных сред, можно отметить, что были
рассмотрены высокопроизводительные системы – на данный момент – одни из лучших,
хотя существует ещё ряд достойных внимания систем(InfiniBand, Gigabit Ethernet и др.).
43
Выбор той или иной коммуникационной среды, безусловно определяется прикладной
задачей, которая диктует требования к пропускной способности и латентности передачи
данных.
1.4.4 Вопросы к разделу 1.4
1. Требования к коммуникационной среде.
2. Достоинства и недостатки коммуникационной среды на основе
масштабируемого когерентного интерфейса SCI.
3. Традиционная область применения SCI.
4. На чём основана технология Myrinet ?
5. Виды использования системы Myrinet.
6. Достоинствами системы и недостатки системы Myrinet.
7. Причины популярности коммуникационной среды QsNet II.
1.5. Коммутаторы вычислительных систем
1.5.1. Типы коммутаторов
Коммутаторы современных ВС отличаются большим разнообразием, так как к
настоящему моменту идут поиски такой конструкции, которая удовлетворяла бы
большинство разработчиков. К наиболее простым относятся коммутаторы 22 (два входа,
два выхода). Существуют также коммутаторы 33, 44 и др. Пример набора коммутаторов
22 представлен на рисунке 1.5.1.
Количество состояний Q таких коммутаторов определяется соотношением
k
Q=2 , где k - количество связей в коммутаторе. При k=1 (см. S1, S2, S4, S8, рисунок
1.5.1) образуются простые коммутаторы первого типа, при k=2 (см. S3, S5, S6, S9, S10,
S12, рисунок 1.5.1) – второго типа, при k=3 (см. S7, S11, S13, S14, риcунок 1.5.1) –
третьего типа, при k=4 (см. S15, рисунок 1.5.1) – четвёртого типа.
Рисунок 1.5.1. Набор коммутаторов с двумя входами и с двумя выходами с
различными типами коммутаций между входами и выходами
44
При создании вычислительных систем используют коммутаторы различных
конфигураций. К наиболее часто применяемым можно отнести следующие:
- простые коммутаторы с временным разделением,
- простые коммутаторы с пространственным разделением,
- сосредоточенные составные коммутаторы,
- распределённые составные коммутаторы.
Коммутаторы с пространственным разделением позволяют соединять любой из
n входов c любым из m выходов. Реализуются такие коммутаторы, как правило, на
основе мультиплексоров и имеют достаточно высокое быстродействие, хотя при этом
аппаратурные затраты достаточно велики. Наиболее часто используются такие
коммутаторы с несколькими входами и выходами, на базе которых в случае
необходимости проектируются составные коммутаторы. Пример коммутатора с
пространственным разделением, реализованного на мультиплексорах, представлен на
рисунке 1.5.2.
Рисунок 1.5.2. Простой коммутатор с пространственным разделением с m входами и n
выходами
К настоящему моменту получили наибольшее распространение распределённые
составные коммутаторы, так как их конфигурация наиболее полно соответствует
требованиям, предъявляемым к ним при проектировании ВС. При создании современных
ВС речь идёт о коммутации сотен, тысяч каналов связи, что реализовать с помощью
составных каналов не представляется возможным. Кроме того, распределение ресурсов
между решаемыми задачами на ВС осуществляется таким образом, чтобы они
располагались компактно, что, естественно, требует распределённости сети в
пространстве. Как правило, такая сеть строится из составных коммутаторов, имеющих m
входов и n выходов, m,n  3.
Сосредоточенные составные коммутаторы строятся на базе простых коммутаторов
с пространственным разделением. В качестве примеров можно привести коммутаторы
Клоза и баньян-сети. Коммутатор Клоза имеет m входов и n выходов и способен
соединять любой вход с любым выходом (см., например, его простейшую реализацию на
рисунке 1.5.1, (структура S15) или представленный на рис 1.5.3, достаточно сложный 128портовый коммутатор, используемый в коммуникационной среде Myrinet).
Коммутатор, содержащий 128 портов, составлен из трёх каскадов простых
коммутаторов 8  8. Задержка на коммутаторе может составить 0.5 микросекунд,
пропускная способность – до 2560 Мбит/с.
Баньян-сети характерны тем, что существует единственный путь от каждого из m
входов к каждому из n выходов (аналогично, простейшая реализация представлена на
рисунке 1.5.1, структуры S5 и S10). В общем случае создаются многокаскадные Баньянсети. Составляющие коммутаторы соединены так, что образуется один путь одинаковой
длины при соединении любого входа с любым выходом.
45
Рисунок 1.5.3. 128-портовый коммутатор фирмы Marinet
В QsNet cистеме используется коммутатор 128  128, представленный на
рисунке 1.5.4. Для построения такого рода коммутаторов разработан кристалл Elite 3.
Рисунок 1.5.4. Коммуникационная среда системы QsNet c коммутатором 128  128,
построенного из коммутаторов 8  8
Этот кристалл представляет собой прямоугольный коммутатор 16х8,
коммутирующий 8 линков в 8 линков. Для подключения одного входного линка
используются 2 порта коммутатора Elite 3, по одному на каждый виртуальный линк.
Пропускная способность порта коммутатора 400 Мбайт/c при задержке 35 наносекунд.
Коммутатор обнаруживает и корректирует искажения пакетов с использованием
содержащегося в них корректирующего кода. Для обеспечения гарантированного качества
доставки пакетов используются два уровня приоритетов в совокупности с механизмом
старения пакетов. Аппаратно поддерживается возможность широковещательных передач
и адаптивной маршрутизации.
На рисунке 1.5.5 и 1.5.6 представлены графики и диаграммы, которые показывают
быстродействие аппаратных реализаций разных технологий, однако кроме аппаратной
производительности на общую производительность обмена влияют программное
обеспечение, текущая задача и аппаратные реализации ВС(например, если количество
запущенных процессов больше, чем процессоров), в таком случае параметры задержки и
скорости передачи данных могут отличаться на 20-40% в худшую сторону.
46
Рисунок 1.5.5. Графики скоростей передачи информации для различных средств связи
Рисунок 1.5.6. Диаграмма времён задержек передачи пакета информации для различных
средств связи
1.5.2
Управление коммутаторами
Управление коммутаторами зависит от способа передачи данных.
Используются следующие способы передачи данных:
- коммутация каналов,
- коммутация сообщений,
- комбинация двух предыдущих способов - коммутация каналов на время передачи.
При коммутации каналов: перед передачей спецально создается канал, по которому будут
передаваться данные, после передачи он удаляется. При коммутации сообщений, они
собираются в пакеты одинакового размера. каждый пакет состоит из заголовка,
передаваемых данных и признака конца пакета.
47
При коммутации пакетов, в коммутаторе используется общая входная очередь
буферов для полного приема пакета. При поступления нового пакета в очередь алгоритм
маршрутизации на основе информации из заголовка пакета вычисляет маршрут
дальнейшего продвижения пакета. При коммутации каналов на время передачи пакета
устанавливается маршрут передачи сообщений (по информации из заголовка пакета), он
считается занятым пока по нему передается весь пакет, включая признак конца
сообщения.
1.5.3 Алгоритмы определения маршрутов
В составных коммутаторах для передачи сообщения со входа на определенный
выход определяется маршрут, проходящий через множество простых коммутаторов с
помощью следующих алгоритмов маршрутизации:
- детерминированные,
- адаптивные,
- частично адаптивные.
Для нахождения оптимального маршрута между входами и выходами
используются детерминированные алгоритмы, но они не учитывают наличие сбоев и
отказов простых коммутаторов. Поэтому применяются адаптивные алгоритмы, которые
обрабатывают сбои и отказы коммутаторов и не выдают ошибок в этом случае. Но такие
алгоритмы довольно объемные и медленнее обрабатываются. Чтобы оптимизировать
работу применяются частично адаптивные алгоритмы, которые при малых отказах
работают как детерминированные, а при ухудшении технических характеристик
функционируют как адаптивные алгоритмы.
1.5.4 Дедлоки в составных коммутаторах
При работе в адаптивных алгоритмах возникают проблемы, связанные с
ограничением числа буферов. Если используется общий буферный пул, то когда алгоритм
маршрутизации нуждается в буфере, он получает любой свободный буфер из пула, при
отсутствии свободных буферов алгоритм ожидает наличие свободного буфера. Такие
блокировки называются дедлоками. Для борьбы с дедлоками применяется различные
методы распределения буферного пула. Одним из таких методов - метод распределения
буферного пула по линкам. Выбирается корневой ВМ, затем от ВМ, который передает
сообщение, строится восходящее дерево до корневого ВМ. После этого корневой ВМ
посылает данный пакет по нисходящему дереву до требуемого ВМ, который указан в
заголовке пакета. Также можно распределять буферный пул по расстояниям. Общий
буферный пул разбивают на классы. Количество классов больше диаметра графа на один.
В каждом передаваемом пакете содержится информация о количестве передач. При
посылке пакета это значение равно нулю. При прохождении через ВМ значение счетчика
передач увеличивается на единицу, т.о. пакет класса n может размещаться в буферах от
одного до n. Так как маршрут конечный, то циклическое ожидание не происходит,
следовательно такая маршрутизация защищает от дедлоков.
Кроме рассмотренных выше методов, используется также метод старения пакетов,
если дедлок продолжается в течении заданного времени, то начинается повторная
передача пакета. Выполняются следующие действия над графом:
- неориентированное ребро графа заменятся противоположно ориентированными
ребрами;
- учитывается порядок прохождения ВМ, без повторного захождения в пройденный ВМ;
48
-
граф разбивается на множество ориентированных подграфов следующим образом:
вершина может принадлежать различным подграфам, а ребро входит только в один
подграф.
В заключение, для оценки средств связи приведём сводную таблицу 1.5.1
сравнения высокоскоростных коммуникационных интерфейсов.
Таблица 1.5.1
Технология
Пропускная
способность
MByte/s
Задержка
мксек/пакет
Поддержка
платформ
Fast Ethertnet
12,5
158
Linux, UNIX,
Низкие цены, популярная
Windows
Gigabit
Ethernet
125
33
Linux, UNIX,
Удобство модернизации
Windows
Myrinet
245
6
Linux, UNIX, Открытый стандарт
Windows
популярная
VI (сLAN от
150
Giganet)
8
Linux,
Windows
SCI
400
1,5
Linux, UNIX, Стандартизирована, широко
Windows
используется
QsNet
340
2
True64 UNIX
AlphaServer SC и системы
Quadrics
Memory
Channel
100
3
True64 UNIX
Используется в Compaq
AlphaServer
Комментарий
Первая аппаратная
промышленная реализация VI
1.5.5 Вопросы к разделу 1.5
1. Назовите типы коммутаторов.
2. Как используются простые коммутаторы ?
3. Назовите коммутаторы коммуникационных сред с большим количеством
портов.
4. Перечислите системы, в которых коммутаторы обеспечивают наибольшую
скорость передачи.
5. Перечислите системы, в которых коммутаторы обеспечивают наименьшее
время передачи.
6. Назначение маршрутизаторов в коммутаторах.
7. Средства борьбы с дедлоками в составных коммутаторах.
8. Назовите параметры, по которым оценивается качество коммутаторов.
1.6 Процесс функционирования вычислительных систем
Процесс функционирования вычислительных систем описывается обобщённым
алгоритмом А, который обеспечивает функционирование множества вычислителей Сi С
и сети G в процессе решения общей задачи. Алгоритм А представляется объединением
к
множеств
А
р
,где Ар – алгоритм, реализованный аппаратно, и объединением множеств
р 1
N 1
программ Pi , P=  Pi , где Pi – i ветвь программы, работающая в i-м узле
i 0
49
N 1
вычислительной системы, таких, что пересечение множеств программ Pi ,

Pi =  .
i 0
N 1
множество D=  D , где Di –
Набором данных для алгоритма А является
i
i 0
набор данных,
используемых в i-м узле вычислительной системы при работе соответствующих
N 1
программ, причём предполагается, что
D
i
.
i 0
Таким образом алгоритм А представлен для коллектива вычислительных
модулей N в виде
N 1
(A  P ),
i
i
i 0
где (Аi * Pi) – композиция из алгоритма и программы, управляющая Сi - м
вычислительным модулем.
Композиция (Аi * Pi) в свою очередь подразделяется на две части: (Аi * Pi)v и (Аi * Pi)o.
(Аi * Pi)v – композиция автономной работы ВМ, которая в том числе выполняет
часть решаемой задачи.
(Аi * Pi)o – композиция взаимодействия ВМ Сi  C с другими вычислительными
модулями.
Разнообразие архитектурных решений сетей связи порождает множество
композиций (Аi * Pi)o
Определение 1.6.1. Аппаратные средства, с помощью которых реализуется
совокупность алгоритмов Ai из множества композиций (Аi * Pi)o для i=0, ... , N-1 и
которые вместе с сетью связей составляют среду для осуществления взаимодействия
между вычислительными модулями ВС, называются коммутатором.
Определение 1.6.2. Программно-аппаратные средства композиции (Аi * Pi)o, для
i=0, … , N-1, которые вместе с сетью связей составляют среду для осуществления
взаимодействия между вычислительными модулями ВС, называются коммутатором с
программируемой структурой.
Как правило, в большинстве вычислительных систем реализуются Ai=Aj и Pi=Pj
для i,j  {0, ... , N-1}, образуя однородные ВС. Эти системы обеспечивают высокую
технологичность производства ВС, и доступность понимания их работы широкому кругу
пользователей.
1.6.1 Вопросы к разделу 1.6.
1.
2.
3.
4.
5.
Какие составные части входят в алгоритм А?.
Какие составные части алгоритма А обычно реализуются аппаратно?
Какие составные части алгоритма А обычно реализуются программно?
Объясните причину разделения композиция (Аi*Pi).
Дайте определение коммутатора и программируемого коммутатора.
1.7 Принципы технической реализации ВС
При технической реализации ВС используются принципы модульности и
близкодействия. Модульность заключается в том, ВС формируется из унифицированных
модулей Mi, i  {0, ... , R}, где R – количество разнообразных модулей, которые
функционально и конструктивно закончены, имеют пространства сопряжения друг с
другом и составляют полный набор, позволяющий решать любую задачу из заданного
класса. Создание ВС представляет собой сопряжение модулей в виде множества
{Mi 1 Mi 2 , … , Mi j , … , Mi n },
50
где Mi
– набор модулей из множества {0, ... , R}.
Модульность ВС обеспечивает :
1) возможность использования любого модуля для выполнения любого
соответствующего задания пользователя;
2) простоту замены одного модуля на другой однотипный;
3) масштабируемость, т.е. возможность увеличения или уменьшения количества
модулей без коренной реконфигурации связей между остальными модулями;
4) открытость системы для модернизации, исключает ее моральное старение.
При конструировании ВС с массовым параллелизмом достаточно ограничиться
единственным модулем, который бы обладал вычислительной и соединительной
полнотой, следовательно, модуль должен иметь средства автономного управления,
располагать АЛУ и памятью и содержать локальный коммутатор – схему для связи с
другими модулями. На практике принято такой модуль называть либо вычислительным
модулем, либо элементарным процессором (ЭП), либо элементарной машиной (ЭМ). При
этом иногда подразумевается, что ЭП – композиция из процессора и локального
коммутатора. Под ЭМ понимается архитектурно более развитая композиция из ЭВМ и
локального коммутатора. В данном учебном пособии использование локального
коммутатора всегда будет оговариваться особо.
Близкодействие
обуславливает
такую
организацию
информационного
взаимодействия между модулями-вычислителями, при котором каждый из них может
непосредственно (без посредника) обмениваться информацией с весьма ограниченной
частью ВМ. Следовательно, структура ВС позволяет осуществлять информационное
взаимодействие между удаленными вершинами ВМ лишь с помощью промежуточных
вершин вычислительных модулей, передающих информацию от точки к точке.
Удаленными считаются вершины, расстояние (диаметр сети) между которыми
больше единицы. Принцип близкодействия допускает реализацию механизма управления
ВС, не зависящий от числа составляющих ее ВМ. Данный принцип, в частности,
выражается в том, что поведение каждого вычислительного модуля Сi  C зависит только
от ограниченного подмножества С*, входящих в С.
Во взаимосвязи с принципом близкодействия, говорят о локальности связи ВМ.
Последнее означает, что состояние вычислительного модуля Сi, i=0, … , N-1 на очередном
временном шаге t+1 зависит от состояния на предстоящем шаге t непосредственно с ним
связанных вычислительных модулей
Cj  С*, т.е. это состояние Ei(t+1) является
функцией:
j
Ei(t+1)=f (Еi(t), Ej 1 (t), Ej 2 (t), ... , Ej q (t)),
где Ej 1 (t), Ej 2 (t),..., Ej q (t) – описания состояний ВМ, принадлежащих множеству С*.
Вычислительные системы, основанные на принципах модульности
и
близкодействия, обладают рядом ценных свойств, таких как децентрализованность,
асинхронность, распределённость.
Асинхронность – функция ВС обеспечивается, если порядок срабатывания ее
модулей определяется не с помощью выработанных тем или иным образом отметок
времени, а достижением заданных значений, как правило, заданной логически функции.
Использование асинхронных схем позволяют достичь в системе алгоритмически
предельного быстродействия. Модули ВС срабатывают немедленно после достижения
соответствующего условия. Применение асинхронных схем обмена информацией между
ВМ позволяет не учитывать разброс в их тактовых частотах и длительностей импульсов
заданных сигналов в линиях связи.
Децентрализованность управления ВС достигается за счёт отсутствия в системе
центрального модуля, который функционирует как единый для всей системы управления.
Децентрализованное управление основано на совместной работе всех исправных модулей
системы. Каждый модуль управляет некоторой локальной областью, примыкающей к
51
этому модулю. Создание таких локальных областей обеспечивает оптимальное или
квазиоптимальное управление.
Очевидно, что такое управление обеспечивает как очень большое значение
живучести ВС (см. раздел 1.8), так и позволяет избежать очередей при обслуживании
заявок на управление. Большое значение живучести достигается за счёт отсутствия
единого центра управления, вероятность выхода из строя которого при прочих равных
условиях гораздо выше, чем отказ ряда ВМ. Очередь при обслуживании заявок на
управление в случае децентрализованного управления разбивается на несколько более
коротких очередей, которые обслуживаются каждая в своей локальной области.
1.7.1. Вопросы к разделу 1.7
1.
2.
3.
4.
5.
В чём заключается сущность модульности и близкодействия ВС?
Дайте определение близкодействию?
В чём достоинства и недостатки децентрализованности управления ВС?
Почему в ВС отдаётся предпочтение асинхронным схемам?
Как увеличить значение живучести ВС?
1.8. Архитектурные особенности ВС
1.8.1. Архитектурные свойства ВС
Следует отметить, что структура ВС приобретает ряд важнейших свойств, которые
обеспечивают вычислительной системе большие преимущества перед ранее
создаваемыми вычислительными комплексами. К таким свойствам относятся:
универсальность, масштабируемость, производительность, реконфигурируемость,
надёжность и живучесть, самоконтроль и самодиагностика, технико-экономическая
эффективность ВС.
Универсальность ВС заключается в том, что она состоит из вычислительных
модулей, имеющих фон-нейманскую или гарвардскую архитектуру, поэтому любая
задача, для которой составлен алгоритм, может быть решена на вычислительной системе.
Эффективность решения этой задачи зависит от того – на сколько хорошо
распараллеливается рассматриваемый алгоритм, сколько вычислителей может быть
использовано для решения поставленной задачи.
Масштабируемость обеспечивает способность к наращиванию и сокращению
производительности ВС, что даёт возможность в течение длительного времени быть
адекватным средством решения сложных задач. Это означает, в частности, что
производительность, достигнутую ВС на заданном количестве ВМ можно увеличить,
подключив к ВС новый вычислительный модуль. Свойство наращивания
производительности предоставляет потенциальную возможность для решения задачи
любой сложности.
Производительность ВС достигается за счет усложнения структуры (наращивание
количества ВМ). Пределы увеличения производительности полностью зависят от свойства
масштабируемости.
Реконфигурируемость ВС бывает статической и динамической. В статическом
режиме приспособление структуры ВС под класс решаемых задач – выбор количества
вычислительных модулей и структуры сети, определяется предварительно на этапе
подготовки задачи к выполнению. При этом возможен, при наличии соответствующего
времени, оптимальный или квазиоптимальный подбор конфигурации сети. При решении
задач в случае дефицита времени их решения, например, решение задач в реальном
масштабе времени, конфигурация сети определяется динамически на основе быстро
решаемых эвристических алгоритмов.
52
Важнейшими свойствами ВС является их надёжность и живучесть.
Определение 1.8.1. Под
надёжностью ВС понимается ее способность к
автоматической настройке и функционированию таких структурных схем, которые при
отказах и восстановлениях вычислительных модулей обеспечивают заданный уровень
производительности.
Заданный уровень производительности, как правило, обеспечивается за счёт
возможности использования определённого числа исправных ВМ, находящихся в резерве.
При изучении надёжности ВС под отказом понимается событие, при котором
система теряет способность выполнять функции, связанные с реализацией параллельной
программы с заданным числом ветвей. Если ВС находится в состоянии отказа, то число
неисправных ВМ, превосходит число вычислительных модулей, составляющих
структурную избыточность. Понятие надёжности ВС, таким образом, совпадает с
общепринятым понятием надёжности сложных систем.
Определение 1.8.2. Под живучестью ВС понимаются свойства вычислительной
системы, которые в условиях отказов и восстановлений вычислителей, гарантируют
производительность в заданных пределах при выполнении параллельной программы даже
в случае отсутствия зарезервированных вычислительных модулей .
Понятие живучести ВС характеризует её способности по организации
отказоустойчивых вычислений или, говоря иначе, по организации выполнения
параллельных программ, допускающих изменение плана распределения ветвей программ
по ВМ в известных пределах. При рассмотрении живучести ВС выделяются полные и
частичные отказы.
Определение 1.8.3. Под полным отказом понимается событие, состоящие в том,
что система теряет способность выполнения параллельной программы.
Определение 1.8.4. Частичным отказом считают события, при которых имеют
место отказы вычислительных модулей, однако сохраняется возможность реализации
на ВС параллельной программы.
Важным фактором функционирования ВС является самоконтроль и
самодиагностика, что обеспечивает её высокую надёжность и живучесть. В качестве
контрольно-диагностического подмножества ВС могут быть использованы любые
исправные ВМ, а в пределах этого подмножества – любой исправный вычислительный
модуль.
Выбор диагностического подмножества ВС производится, как правило,
автоматически.
Не менее ценным свойством ВС является конструктивная однородность, что резко
повышает её технико-экономическую эффективность. Это свойство ВС позволяет резко
сократить сроки её разработки, приводит к высокой технологичности производства,
упрощает статическую и динамическую реконфигурацию, облегчает их техническую
эксплуатацию.
1.8.2. Схема обмена информацией между ветвями параллельных
алгоритмов
Пусть Р программа состоит из n ветвей. Ясно, что обмен информацией между
ветвями P программы может быть реализован с помощью дифференцируемого обмена,
при этом обмене производится передача из одной ветви в любую другую ветвь или, что то
же самое, из одного ВМ к другому, от передатчика к приёмнику. При такой организации
обмена использование вычислительных ресурсов малоэффективно.
53
Рисунок 1.8.1. Дифференцируемый обмен
Существуют также коллективные (групповые) обмены информацией. К ним
относятся:
1) трансляционный,
2) трансляционно-циклический,
3) конвеерно-параллельный,
4) колекторный.
1) При трансляционном обмене (one to all broadcast) осуществляется передача
одной и той же информации из одной любой ветви во все ветви параллельного алгоритма.
Рисунок 1.8.2. Трансляционный обмен. Затенённый квадрат является передатчиком
информации
2) Трансляционно-циклический (all to all broadcast) реализует передачу
информации из каждой ветви во все остальные, следовательно, если трансляционный
обмен выполняется за 1 такт, то трансляционно-циклический – за n тактов.
Рисунок 1.8.3. Трансляционно-циклический обмен. Затенённый квадрат является
передатчиком информации
54
3) Конвеерно-параллельный обмен, обеспечивает передачу информации между
соседними ветвями, за 2 такта. например, при чётном n в первом такте
осуществляется передача данных из ветвей Р1, Р3,… , Рn-1 в ветви Р2, Р4, … , Рn. Во
втором такте обеспечивается передача информации из ветвей Р2, Р4,… , Рn в ветви
Р1, Р3, … , Рn-1 .
1
2
3
4
а)
n
•••
1
2
3
4
n
•••
б)
•••
n+1
n+2
n+3
n+4
2n
•••
Рисунок 1.8.4. Конвеерно-параллельный обмен. Затенённые квадраты являются
передатчиками информации. Передача а). Нечётные ВМ передают информацию чётным.
Передача б). Чётные ВМ передают информацию нечётным и т.д. В ВС может быть
организовано несколько конвееров.
4) Коллекторный обмен. Это по сути инвертированный трансляционный обмен.
Вычислительный модуль передатчик становится приемником. В одну ветвь собирается
информация из m≤ n ветвей. Такой обмен требует m тактов и реализуется как
последовательность m дифференцируемых обменов.
Рисунок 1.8.5. Коллекторный обмен. Затенённые квадраты являются передатчиками
информации
Имеется статистика частоты использования схем обмена информацией при
реализации крупноблочных параллельных алгоритмов, которая представлена в
таблице 1.8.1.
Таблица 1.8.1.
ДО
ТО
ТЦО
КПО
КО
2%
17%
40%
34%
7%
Тип обмена
Частота использования
55
1.8.3. Опыт применения методики крупноблочного распараллеливания
сложных задач
При разработке новых вычислительных технологий стоит учитывать накопленный
опыт многолетнего параллельного программирования и конструирования,
заключающийся в следующих выводах:
1. При решении сложных задач их следует разбивать на несколько параллельных
ветвей, состоящих из одинаковых последовательных частей, которые легко разрабатывать.
2. Между параллельными ветвями алгоритма данные нужно распределять
одинаковыми объемами и так, чтобы было легко установить взаимно однозначное
соответствие между адресами или номерами этих данных и номерами ветвей.
3. При разработке алгоритмов нужно использовать перечисленные выше схемы
обмена информацией между ВМ: дифференциальную, трансляционную, трансляционноциклическую, конвеерно-параллельную, коллекторную. При обмене по этим схемам
информация транзитно проходит через ВМ, находящиеся на её пути до ВМ-приёмника.
Но если принять эти схемы обмена как виртуальные, то обмен информации можно
производить как пересылку между соседними вычисдителями.
4. Так как такие схемы обмена довольно просты, то можно использовать
однородные структуры ВС: линейку, кольцо, решетку, гиперкуб и тор.
5. Для реализации параллельных алгоритмов сложных задач нужно использовать
версии распространённых языков высокого уровня со средствами организации обмена
между ВМ: Фортран, Си и другие. В таком случае увеличение трудоёмкости на 10% от
трудоёмкости последовательного программирования.
6. При использовании простой схемы обмена данными между ВМ – простота
разработки параллельных программ, так как реализация обмена между ВМ – не меньше
10% общего объема программы.
7. Трансляционно-циклическая, трансляционная и конвеерно-параллельная схема
обмена основаны на одновременной работе всех ВМ и используются не менее, чем в 90%
реализаций параллельных программ сложных задач. Чем больше объем исходных данных,
тем меньшее время необходимо для обмена данными между ветвями программы.
1.8.4. Архитектурные аспекты при создании ОС ВС
1. Архитектура ВС должна обеспечивать организацию параллельных вычислений
во всех режимах. Есть множество вариантов подобных организаций. Некоторые из них
даже обеспечивают построение одинаковых параллельных ветвей, таких что каждая из
них содержит операторы для преобразования данных, находящихся в памяти выделенного
для этой ветви ВМ, следовательно реже обращения к памяти других ВМ. Такая
организация уменьшает требования к скорости обмена данными между ВМ.
2. При разработке параллельных алгоритмов следует учитывать, что вычисления –
это совокупность одновременных асинхронных взаимодейстующих процессов
(последовательных воздействий на части ресурсов системы при реализации некоторого
алгоритма в реальном времени).
Совместимость процессов - это не только обычная для мультипрограммных систем
(в частности систем разделения времени) одновременность протекания алгоритмически
независимых процессов (разделение ресурсов ВС), но и наличие связи между некоторыми
процессами, так как они на самом деле части одного сложного алгоритма(объединение
ресурсов ВС).
56
1.8.5. Структурные характеристики ВС
Структурные характеристики ВС определяют некоторые обобщённые параметры
ВС, которые могут быть использованы при планировании решения параллельных задач. К
ним относятся структурные задержки при передаче информации между узлами,
структурная коммутируемость и структурная живучесть ВС.
1) Структурные задержки при передаче информации между узлами
характеризуются диаметром и средним диаметром сети. Диаметр сети определяет, в
конечном счёте, максимально возможное количество транзитных вычислительных
модулей при установке связи между заданными. Средний диаметр определяет
усреднённое количество транзитных ВМ, которые могут связываться с заданным.
2) Структурная коммутируемость ВС определяется соотношением

K (G, S, S’) = {Kn (G, S, S’)}, n  {1, 2, … ]N/2[ },
где N – количество вычислительных модулей в рассматриваемой ВС, Кn – координата,
определяющая вероятность реализации в системе при заданной структуре сети G с
заданными коэффициентами готовности сети S’ и вычислительного модуля S,
n непересекающихся межмашинных взаимодействий, ]N/2[  N/2 – функция выделения
целой части числа.
S=  (   ) и S’=  ' ( '  ' ) ,
где  – интенсивность восстановления вычислительного модуля или среднее число
восстановления его в единицу времени,  – интенсивность потока отказов (лямда
характеристика вычислительного модуля),  ’ – интенсивность восстановления узла связи
или среднее число восстановления его в единицу времени,  ’ – интенсивность потока
отказов узла связи (лямда характеристика узла связи).
 ,  ’ – в установившемся режиме есть величины постоянные и характеризуют
технологические особенности изготовления и эксплуатации ВС, величины  и  ’ имеют,
как правило, случайный характер, так как зависят от многих факторов, в том числе и от
человеческих.
3) Структурная живучесть ВС оценивается вектор функцией:

L (G, S, S’) = {Lr (G, S, S’)}, r  {2, 3, …, N},
где Lr – является вероятностью существования подсистемы ранга r, т.е. подмножество из r
работоспособных вычислительных модулей, связность которых устанавливается через
работоспособные линии связи.

Структурная коммутируемость K характеризует способность ВС по реализации
обмена между ВМ. При этом требуется чтобы:
1. При дифференцируемом обмене имелась возможность реализации одного
обмена между двумя вычислительными модулями.
2. При трансляционном обмене реализовывалась бы одновременная передача
информации от одного ВМ во все остальные.
3. При конвеерно-параллельном обмене выполнялось одновременно ]N/2[
взаимодействий между ]N/2[ парами вычислительных модулей.

Структурная живучесть L характеризует способность ВС к условиям отказа
вычислительных модулей и/или линий связей - порождать подсистемы ВС тех или иных
рангов, следовательно, способность ВС к решению задач заданной сложности в условиях
вышеупомянутых отказов.
57
При синтезе структур ВС может быть поставлена задача поиска максимума
функции структурной живучести ранга r:
max Lr(G, S, S’) = Lr(G*), при заданных значениях N,r,V,S,S’,
где V – количество связей входов и/или выходов из узла.
Найденная структура сети G* по своим параметрам является оптимальной. В
общем случае найти оптимальное решение достаточно сложно, поэтому часто
рассматриваются упрощённые задачи, которые при их решении дают квази оптимальные
решения.
Так, например, ставится упрощённая задача для графов Dn и Л(N, v, q) (см. разделы
1.3.9 и 1.3.13), при решении которой используются две гипотезы, которые обычно
подтверждаются:
1) Структура G*, при которой достигается максимум живучести Ln(G*) ранга n,
обеспечивает максимум живучести Lr(G*) ранга r.
2) Структура с минимальным диаметром относится к G* и обладает максимальной
структурной живучестью.
На практике, обычно, структуру G* называют оптимальной. Эта структура имеет
при заданном порядке N, максимальную степени вершины v и минимальный диаметр.
1.8.6. Классификация структур ВС
При создании классификации структур, в частности ВС, преследуются различные
цели, связанные с усиленным вниманием разработчиков к тем или иным аспектам
решения некоторых проблем, поэтому к настоящему моменту существует несколько
классификаций. Мы выберем наиболее часто используемую классификацию Джона
Флинна, предложенную в 1966г., так как она отображает этапы развития вычислительных
систем. Существуют четыре класса структур ВС: SISD (OKOD), MISD (MKOD), SIMD
(OKMD), MIMD (MKMD).
1) К первому классу относится SISD – single instruction stream/single data stream,
Одиночные Команды/Одиночные Данные. Это наиболее простая структура, возникшая в
эпоху изобретения вычислительных машин. Её структура представлена на рисунке 1.8.6.
Устройство управления
Арифметикологическое
устройство
Память
Рисунок 1.8.6. Структура вычислительной системы SISD
Эта структура отображает ЭМВ, которые появились вначале этапа развития
вычислительной техники, и может рассматриваться как составной элемент
вычислительной системы. Она включает устройство управления, которое формирует
управляющие последовательности сигналов, выдаваемые в память ЭВМ и арифметикологическое устройство. Память ЭВМ хранит исходные данные и полученные результаты.
58
Арифметико-логическое устройство производит запрограммированные арифметические и
логические операции.
2)
Ко второму классу относится МISD – multiple instruction stream/single data stream,
Множественные Команды/Одиночные Данные. Это структура появилась как дальнейшее
развитие структуры ЭВМ, с целью увеличения скорости её работы за счёт разложения
арифметико-логических операций на более элементарные, которые затем выполняются
последовательно друг за другом. Такая структура позволяет выполнять одновременно
несколько арифметико-логических операций. Структура MISD представлена на
рисунке 1.8.7. ЭБОi – i-й элементарный блок обработки
Конвейер элементов блоков обработки
ЭБО1
ЭБОn


Поток данных
Поток результатов
Память




Рисунок 1.8.7. Структура вычислительной системы МISD.
3) Ко третьему классу относится структура single instruction stream/ multiple data
stream, Множественные Команды/Одиночные Данные. Это структура появилась как
дальнейшее развитие вычислительных комплексов, с целью увеличения скорости их
работы за счёт построения такого вычислительного процесса, когда одна программа на
разных вычислителях (элементарных процессорах) обрабатывает различные данные,
которые относятся к решаемой задаче. Такая система ещё называется системой с
массовым параллелизмом. Эта структура представлена на рисунке 1.8.8. ЭПij (i=1, … , n,
j=1, … , m) – элементарный процессор, УУ – устройство управления.
УУ
ЭП11
ЭП12

ЭП21
ЭП22


ЭПn1


ЭП n2
ЭП1m

ЭП n m
Рисунок 1.8.8. Структура вычислительной системы SIMD
4) К четвёртому классу относится структура MIMD – multiple instruction
stream/ multiple data stream, Множественные команды/ Множественные данные. Такого
рода системы объединяют в себе свойства систем классов SIMD и MISD. В системе
59
имеется n вычислительных модулей, каждый из которых может быть выполнен по
конвейерной схеме, имеет свою локальную память и локальный коммутатор. Для обмена
может существовать общее поле памяти. Выделяется один или несколько ВМ для
управления процессом обработки информации. При использовании нескольких
управляющих вычислительных модулей образуются локальные области ВС, которые
могут функционировать автономно. При использовании одного ВМ в качестве
управляющего образуется подкласс MIMD – кластерные системы. Структура класса
MIMD показана на рисунке 1.8.9. SIMDij, (i=1, … , n, j=1, … , m). На этом рисунке в
качестве вычислителей использованы структуры SIMD, хотя, в общем случае могут быть
использованы любые конфигурации вычислительных модулей.
SIMDm
SIMD2
SIMD 1
SIMD 11
SIMD12

SIMD1m
SIMD21
SIMD22

SIMD2m

SIMDn1
+

SIMDn2


SIMDn m
Рисунок 1.8.9. Структура вычислительной системы MIMD
1.8.7. Вопросы к разделу 1.8.
1. Причины появления у ВС таких свойств как масштабируемость,
производительность, реконфигурируемость.
2. В чём разница между понятиями надёжность и живучесть ВС?
3. Назовите пять способов обмена информацией между ВМ.
4. Какие существуют методы исследования структурной живучести?
5. Какие признаки положены в основу классификации ВС?
60
ГЛАВА 2. РЕАЛИЗАЦИЯ ПАРАЛЛЕЛЬНЫХ
АЛГОРИТМОВ
2.1. Реализация параллельных алгоритмов
2.1.1. Определение параллельного алгоритма
Создание общепринятых методов построения параллельных алгоритмов, несмотря
на значительные усилия в этой области, пока не увенчалось успехом. Поэтому для
изучения этой проблемы введём существующие к настоящему моменту и определения и
достижения, которые уже существуют.
Определение 2.1.1. Параллельный алгоритм – это описание процесса обработки
информации, ориентированное на реализацию вычислительный системой.
Параллельный алгоритм решения задач составляет основу параллельной
программы Р.
Определение 2.1.2. Запись параллельного алгоритма на языке программирования,
доступного для вычислительной системы, называется параллельной программой, а сам
язык параллельным.
При решении параллельных задач существуют два метода распараллеливания,
связанные с условиями эксплуатации ВС:
Статический метод. В случае наличия достаточно большого времени для
подготовки задачи к решению (построения схемы распараллеливания, оптимизированного
плана решения задачи, программирование и отладка программы и т.д.).
Динамический, используется чаще всего в системах реального времени и
требует немедленной реакции на сложившуюся ситуацию: запущена заранее
подготовленная программа, предоставлены все необходимые вычислительные ресурсы,
обеспечен доступ к исходным данным и транспортировка полученных результатов в
требуемые места. Частично эти ситуации планируются заранее, частично выделение
ресурсов осуществляется за счёт аварийных завершений второстепенных задач.
С точки зрения технической реализации существуют три способа
распараллеливания сложных задач: локальное, глобальное и смешанное.
1) При локальном распараллеливании в выполняемой программе выделяются
участки машинных команд, которые могут выполняться параллельно.
2) Глобальное распараллеливание происходит на уровне процедур и/или функций
(на уровне программных модулей).
3) Смешанное распараллеливание, наиболее эффективное, совмещает первый и
второй способы.
При первом способе распараллеливания транслятором на этапе трансляции
программы и/или с помощью аппаратных средств, включённых в вычислительный
модуль, определяется участок программы, который может выполнятьcя параллельно.
Реализуются различные схемы распараллеливания с помощью аппаратных средств. В
качестве примера можно привести суперскалярные и мультитредовые процессорные
системы [17]. Рассмотрим организацию параллельных вычислений с помощью
суперскалярных процессоров.
Суперскалярным (этот термин впервые был использован в 1987 году) процессором
называется центральный процессор, который одновременно выполняет более чем одну
команду. Это достигается за счёт включения в состав процессора нескольких
самостоятельных функциональных (исполнительных) блоков, каждый из которых
отвечает за свой класс операций и может присутствовать в процессоре в нескольких
экземплярах. Так, в микропроцессоре Pentium III блоки целочисленной арифметики и
операций с плавающей точкой дублированы.
61
Суперскалярные микропроцессоры имеют многоуровневую иерархическую память,
включая до трёх уровней кэш-памяти; раздельные кэш-памяти команд и данных;
устройство выборки команд, обеспечивающее выборку на исполнение совокупности
команд, принадлежащих «окну исполнения». Составляются также таблицы предсказания
переходов; переименование регистров; поддержка внеочередного исполнения команд;
набор функциональных устройств для преобразования данных в форматах с
фиксированной и плавающей точкой.
Значительный объём оборудования микропроцессора используется для того, чтобы
загрузить
работой,
посредством
динамического
распараллеливания,
набор
функциональных устройств.
Следует подчеркнуть использование разнесенных архитектур при построении
микропроцессоров. Это дает возможность организовать параллельную обработку на
уровне операций с фиксированной точкой и операций с плавающей точкой [16]. При
скалярной обработке разнесенная архитектура позволяет достигать производительности,
характерной для векторных процессоров, за счет предвыборки данных из памяти и
автоматической развертки нескольких последовательных витков цикла в адресном
процессоре.
С точки зрения требований к технологии программирования суперскалярные
микропроцессоры предполагают группировку обрабатываемых данных. Это необходимо
для эффективной работы многоуровневой памяти с одним или несколькими уровнями
памяти. Группировка выполняется программистом или компилятором.
Обычно программисты группируют зависимые операторы в статические
структуры, что помогает понимать программу, но препятствует выделению независимых
операторов. Для решения этой проблемы существуют оптимизирующие компиляторы,
которые пытаются переупорядочить операторы так, чтобы в «окно исполнения» попадало
как можно больше независимых операторов.
2.1.2. Организация динамического распараллеливания в суперскалярных
микропроцессорах
Существует два класса процессоров по отношению к параллельной обработке
данных. Первый класс – суперскалярные. В них нет никакого указания на параллельную
обработку в системе команд. В других процессорах, наоборот, в специально отведённых
полях команды каждому из параллельно работающих обрабатывающих устройств
предписывается действие, которое устройство должно совершить. Такие процессоры
называются процессорами с длинным командным словом(VLIW).
Последовательное программирование предполагает выполнение команд одна за
другой. Но в программе встречаются команды, независимые по управлению или данным,
поэтому их можно выполнять параллельно. Зависимость по управлению, которые
проявляются как переходы по условию, представляют главное препятствие параллельному
выполнению потому, что эта зависимость должна быть определена прежде, чем будут
выполнены все последующие команды
Благодаря изменениям статической (изменения в исходном коде программы) и
динамической (изменения зависимостей по управлению и по данным) структур
программы можно повысить эффективность параллельного выполнения программы. Но не
всегда возможно изменить код программы, так как это может привести к увеличению
времени выполнения.
Архитектура суперскалярных микропроцессоров использует модель окна
исполнения. При исполнении программы микропроцессор как бы продвигает по
статической структуре программы окно исполнения, ширина которого задаёт количество
команд программы, исследуемых на возможность одновременного исполнения.
62
Желательно, чтобы в окно попадали как можно больше независимых команд, что
значительно повышает параллельную обработку команд.
Предсказание переходов на сегодняшний день рассматривается как один из
наиболее эффективных способов борьбы с конфликтами по управлению. Идея
заключается в том, что еще до момента выполнения команды условного перехода или
сразу же после ее поступления на конвейер делается предположение о наиболее
вероятном исходе такой команды(переход произойдет или не произойдет). Если
предсказание было сделано верно, то результаты условно выполненных команд
сохраняются. При ошибочном предсказании состояние процессора восстанавливается на
момент принятия решения о выполнении перехода. Рассмотрим некоторые механизмы
предсказания переходов.
Статическое предсказание переходов осуществляется на основе некоторой
априорной информации о подлежащей выполнению следующего участка программы.
Предсказание делается на этапе компиляции программы и в процессе вычислений уже не
меняется. Главное различие между известными механизмами статистического
прогнозирования заключается в виде информации, используемой для предсказания, и ее
трактовке.
Известные стратегии статистического предсказания для команд условного
перехода можно классифицировать следующим образом:
- переход происходит всегда;
- переход не происходит никогда;
- переход выполняется по результатам профилирования (под профилированием
понимается выполнение программы на некотором эталонном наборе исходных данных,
сопровождающееся сбором информации об исходах каждой команды условного
перехода);
- переход определяется по коду операции;
- переход выполняется исходя из направления;
- при первом выполнении переход имеет место всегда.
В динамических стратегиях решение о наиболее вероятном исходе команды
условного перехода принимается в ходе вычислений, исходя из информации о
предшествующих переходах, собираемой в процессе выполнения программы. Эта
информация хранится в специальной таблице истории. Таблица организуется по
ассоциативному принципу, подобно кэш-памяти, ее элементы доступны по адресу
команды, ветвление которой предсказывается. В некоторых реализациях элемент таблицы
предсказания ветвления является счётчиком, значение которого увеличивается при
правильном предсказании и уменьшается при неправильном. Алгоритм предсказания
зависит от размера строк таблицы истории.
Команды, помещенные в окно исполнения, могут быть зависимы по данным. Для
пояснения сущности взаимосвязи команд по данным положим, что две команды (а и в)
предусматривают обращение к одной и той же переменной х, причем команда а
предшествует команде в. В общем случае между а и в ожидаемы три типа конфликтов по
данным:
- «чтение после записи» (ЧПЗ): команда в читает х до того, как команда а успела
записать новое значение х, то есть команда в ошибочно получит старое значение х вместо
нового.
- «запись после чтения» (ЗПЧ): команда в записывает новое значение х до того, как
команда а успела прочитать х, то есть команда а ошибочно получит новое значение х
вместо старого.
- «запись после записи» (ЗПЗ): команда в записывает новое значение х прежде, чем
команда а успела записать в качестве х своё значение, то есть х ошибочно содержит а-е
значение х вместо в-го.
63
Возможен и четвертый случай, когда команда в читает х прежде команды а. Этот
случай не вызывает никаких конфликтов, поскольку как а, так и в получат верное
значение х.
Лишние зависимости появляются по нескольким причинам: не оптимизированный
программный код, ограничение количества регистров, стремление к экономии памяти,
наличие программных циклов.
Команды могут выполняться параллельно после устранения зависимостей по
данным и управлению. Формирование расписания параллельного выполнения команд
возлагается на аппаратные средства микропроцессора.
В число основных блоков суперскалярного микропроцессора входят: блок выборки
команд и предсказания переходов, блок декодирования команд анализа зависимостей
между командами, переименования и диспетчеризации. Входят также блок регистров и
обрабатывающих устройств с плавающей и фиксированной точками, блок управления
памятью, а также блок упорядочения выполненных команд.
Рассмотрим основные приемы повышения быстродействия в суперскалярных
микропроцессорах.
2.1.3. Предварительная выборка команд и предсказание переходов
В современных мультипроцессорах повышенные требования предъявляются к
пропускной способности интерфейса «микропроцессор-память». Это связано с тем, что
при обработке необходимо извлекать из памяти за один такт несколько команд. Также в
систему кэширования вводятся средства предсказания переходов, основное назначение
которых – повысить вероятность наличия в кэш-памяти, требуемой команды.
Этапы исполнения условных ветвлений:
1) распознавание команды условного ветвления;
2) проверка выполнения условного перехода;
3) вычисление адреса перехода;
4) передача управления в случае перехода.
На
каждом
этапе
используются
специальные
приемы
повышения
производительности.
1. Для ускорения декодирования используются либо дополнительные биты в поле
команды, либо предварительное декодирование команд при их выборке из кэш-памяти
команд.
2. Часто встречается ситуация, что команда уже выбрана из кэш-памяти, а условие
перехода еще не известно. Тогда необходимо использовать предсказание переходов,
рассмотреное в предыдущем разделе.
3. Чтобы определить адрес ветвления необходимо выполнить целочисленное
сложение содержимого счётчика команд и смещения, заданного в поле команды
ветвления. Для ускорения вычисления адреса можно использовать буфер, содержащий
ранее использованные адреса переходов.
2.1.4. Декодирование команд, переименование ресурсов и диспетчеризация
При декодировании команды создаётся одна или несколько троек, каждая из
которых включает исполняемую операцию, адреса операндов и адрес размещения
результата.
Использование механизма динамического отображения логических ресурсов на
физические ресурсы микропроцессора помогает избавиться от лишних «записей после
чтения» или « записей после записи» зависимостей.
Для устранения зависимости по данным используется метод, известный как
переименование регистров. Основная идея переименования регистров состоит в том, что
64
каждый новый результат записывается в один из свободных в данный момент физических
регистров, при этом ссылки на заменяемый регистр во всех последующих командах
соответственным образом корректируются. Программист, составляющий программу,
имеет дело с именами логических регистров. Рассмотрим два основных способа
переименования. В первом физический файл регистров превышает логический. При
необходимости переименования используется регистр из списка свободных и ему
сопоставляется соответствующее логическое имя.
Например, пусть нужно выполнить команду sub r3, r3, 5 (из значения регистра r3
вычесть 5 и записать результат в r3). Пусть в момент исполнения команды в таблице
логическому регистру r3 соответствует физический R1. Первый регистр в списке
свободных - R2. Тогда в поле результата команды sub r3, r3, 5 регистр r3 замещается R2.
Тогда на самом деле выполняется команда sub R2, R1, 5. А следующая команда, которой
нужен результат sub, должна обращаться к R2.
Второй способ переименования использует равное число логических и физических
регистров и сохраняет их однозначное соответствие. Для каждой инициированной на
исполнение команды имеется буфер, называемый «переупорядочивающимся». Этот буфер
похож на FIFO очередь, выполненную в виде кольцевого буфера с указателями «начало» и
«конец». Команды помещаются в конец буфера. По завершению команды ее результат
заносится в заранее предписанный ей элемент очереди, независимо от места в очереди,
занимаемого этим элементом. Как только команда достигнет начала буфера и она будет
выполнена, ее результат записывается в регистр, а сама команда удаляется.
В момент декодирования команды значению ее результата выбирается
соответствующая
упорядоченной
тройке
команды
позиция
в
элементе
переупорядочивающего буфера, в котором размещается рассматриваемая декодированная
команда, и делается отметка в таблице соответствия значений о том, что значение
результата может быть найдено в соответствующем элементе буфера.
2.1.5. Исполнение команд
После того, как сформированы код операции и физические операнды (источник и
результат) и размещены в буферах, наступает фаза динамической проверки готовности
значений операндов для исполнения команды.
Существует ряд ограничений исполнения команды, связанных с доступностью
физических ресурсов (функциональных устройств, коммутаторов). Существует 3 метода
для организации окна исполнения: одной очереди, многих очередей и метод
резервирующей станции.
В методе одной очереди переименование регистров не нужно, так как бит
резервирования каждого регистра определяет доступность значений операндов. Регистр
освобождается, когда команда исполняется.
В методе многих очередей команды распределяются по очередям в зависимости от
своего типа, например, очередь для команд с плавающей точкой.
Метод резервирующей станции был разработан Р.Л.Томасуло в 1967 году и
впервые воплощён в вычислительный модульной системе IBM 360/95. После выборки и
декодирования команды распределяются по схемам резервирования тех функциональных
блоков, где команда будет исполняться. В резервирующей станции команда запоминается
и по готовности выдается в соответствующий данному пункту функциональный блок.
Выдача происходит только, если команда получила все необходимые операнды, и
функциональный блок свободен. Иногда резервирующая станция содержит не сами
операнды, а указатели на них в регистровом файле или в переупорядочивающем буфере.
Отметим одну особенность рассматриваемой схемы: не требуется, чтобы операнд был
обязательно занесен в отведенный для него регистр – он может быть ускоренно передан
65
прямо в резервирующую станцию для немедленного использования или сохранён там для
последующего использования.
Кэш команд
Переименование
регистров
Выборка команд
Декодирование
команд
Работа с
памятью
Резервирующая
станция
Кэш данных
Блок переходов
АЛУ
Рисунок 2.1.1. Процесс функционирования процессора с внеочередным исполнением
команд
Эффективность применения внеочередного исполнения команд [18] демонстрирует
таблица 2.1.1, в которой приведены значения производительности для микропроцессоров
без изменения порядка исполнения команд и с внеочередным исполнением команд,
имеющих
одинаковое
количество
функциональных
устройств.
Процесс
функционирования процессора с внеочередным исполнением команд иллюстрирует
рисунок 2.1.1.
Таблица 2.1.1
Микропроцессор
Mips R5000/180
Mips R10000/180
Pentium/200
Pentium Pro/200
Alpha 21164/600
Alpha 21264/575
SPECint
4,82
8,59
5,47
8,09
19,3
30,3
Ускорение
1,78
1,48
1,57
2.1.6. Работа с памятью
Часто при применении ВМ случается ситуация, когда вся программа не
помещается в оперативной памяти целиком из-за своего большого размера. Но без этого
можно обойтись, так как в каждый момент времени «внимание» машины концентрируется
на определенных сравнительно небольших участках программы. Таким образом, нужно
хранить только используемые в данный момент времени части программ, а остальные
части могут быть во внешней памяти. Сложность такого варианта решения проблемы в
том, что процессы обращения к оперативной памяти и запоминающих устройствах
существенно различаются, и это затрудняет программирование. Решением этой проблемы
было появление в 1959 году идеи виртуализации памяти, под которой понимается метод
автоматического управления иерархической памятью, при котором программист
представляет, что он имеет дело с единой памятью большого размера и высокого
быстродействия (виртуальной памятью).
66
Если используется виртуализация памяти оперативная память выглядит как
линейное пространство К адресов. Для задач, которым не хватает такого размера памяти,
выделяется большее пространство адресов (виртуальное пространство). При написании
программы используют виртуальные адреса, но при выполнении необходимо, чтобы
текущие команды и операнды были в оперативной памяти, т. е. нужно соответствие между
виртуальными и физическими адресами. Для этого при выполнении программы
необходимая информация, на которую ссылается виртуальный адрес, из внешней памяти
переписывается в оперативную, а потом её адрес заменяется на физический. Этими
операциями занимается операционная система, которая заменяет номера виртуальных
страниц на номера физических страниц, находящихся в основной памяти. Трансляция
адресов происходит с помощью таблицы страниц, в которой число записей соответствует
количеству виртуальных страниц. От способа реализации страничной таблицы зависит
эффективность техники виртуальной адресации, потому что при каждом обращении к
памяти необходимо прочитать информацию из таблицы страниц. Самый быстрый способ
– хранение в специальных регистрах, но если объем таблицы большой, то практически
можно использовать только один вариант – хранение таблицы в основной памяти, хотя
время доступа к такой информации в два раза больше. Чтобы уменьшить время доступа,
можно использовать дополнительное устройство в составе ВМ – буфер быстрого
преобразования адреса, которое представляет собой кэш память.
При каждом новом запросе к оперативной памяти транслятор адресов сначала
просматривает кэш-память, есть ли там номер требуемой физической страницы, так как
при каждой трансляции адресов результат заносится в кэш-память: номер физической
страницы в память данных, а виртуальной – в память тегов. Таким образом, в памяти
тегов хранятся результаты нескольких последних операций преобразования адресов..
Номер виртуальной страницы
Память тегов
V R M
A Номер физической страницы
Память данных
Рисунок 2.1.2. Структура буфера быстрого преобразования адресов
Если номер страницы найден в кэш-памяти, то он используется при обращении к
памяти. Если поиск неудачен, то процедура преобразования адресов использует
страничную таблицу, после чего результат «номер виртуальной страницы – номер
физической страницы» записывается в кэш-память. Структура кэш-памяти показана на
рисунке 2.1.2.
Каждая запись содержит четыре признака:
1) Признак присутствия V равен единице, если виртуальная страница в данный
момент загружена в основную память. И в памяти данных находится соответствующий
номер физической страницы. Если V=0, то преобразователь адреса генерирует сигнал
страничного сбоя, и операционная система выполняет загрузку страницы с диска в
оперативную память.
2) Признак использования страницы R равен 1 если к странице выполняется
доступ. Этот признак используется в алгоритме замещения страниц для выбора той из
них, которую можно удалить из ОП наиболее безболезненно, чтобы освободить место для
новой.
3) Признак модификации страниц М служит для определения идентичности
страниц, находящихся в ОП и на диске. При удалении страницы из ОП проверяется
67
равенство M=1 (страница изменена), тогда страницу перед удалением обязательно нужно
переписать на диск.
4) Признак прав доступа А необходим для защиты информации. Он определяет вид
доступа к странице: только для чтения (R), только для записи (W), для чтения и для
записи (RW).
Как буфер преобразования адресов обычно используется полностью ассоциативная
или множественно-ассоциативная кэш-память с высокой степенью ассоциативности и
временем доступа, близким к аналогичным показателям для кэш-памяти первого
уровня (L1). Число входов у типовых буферов определяет размер части виртуального
пространства, к которой осуществляется быстрый доступ, и обычно невелико(64-256).
2.1.7. Завершение выполнение команды
Цель этого этапа заключается в сохранении последовательного алгоритма
программы при распараллеливании отдельных команд и условном выполнении команд
ветвленияю Выполнение команды заканчивается при изменении состояния процессора,
для этого есть 2 способа:
состояние процессора хранится в буфере истории вычислений или в наборе
контрольных точек, которые можно использовать для восстановления состояния, когда
это необходимо;
используется переупорядочивающийся буфер, в котором для всех команд
хранятся специальные значения счетчика команд и остальных регистров, необходимых
для обработки прерываний. При этом у процессора подразумевается два состояния:
логическое (зависит от результата условно выполненных команд) и физическое
(изменяется при завершении текущей команды).
2.1.8. Направления развития суперскалярной архитектуры
В настоящее время принимаются попытки реализовать механизм параллельного
исполнения команд в суперскалярных процессорах. При этом необходимо учитывать
зависимость по данным между этими командами.
В суперскалярном процессоре команды исследуются по мере выполнения. Эти
исследования связаны с выявлением и обработкой команд переходов, их
прогнозированием, идентификацией типа команды и направлением команды на
соответствующее функциональное устройство. Также выполняется переименование
регистров для смягчения зависимостей по данным.
Существуют некоторые ограничения эффективности, накладываемые на
суперскалярные архитектуры. Первое ограничение связано с условными переходами, их
предсказанием. Второе ограничение вытекает из размера окна исполнения, от размера
которого зависит количество параллельно выполняемых команд.
Теперь рассмотрим процессоры с длинным командным словом(VLIW). Они имеют
ряд достоинств. По сравнению с суперскалярными архитектурами VLIW-процессор более
эффективно исследует зависимости между командами и имеет более простое устройство
управления, и имеет более высокую тактовую частоту.
Но у VLIW-процессора есть серьезный недостаток. Это команды ветвления,
зависящие от данных, значения которых становятся известны только в процессе работы
программы. VLIW-процессор требует большого размера памяти имен, многовходовых
регистровых файлов. Также VLIW-процессор имеет сравнительно небольшое окно
исполнения из-за отсутствия у компилятора информации о зависимостях, формируемых в
процессе выполнения.
68
Ввиду всех недостатков VLIW-процессоров, суперскалярные процессоры
преобладают на рынке микроэлектроники, и постоянно совершенствуются и развиваются.
При этом необходимо исследовать производительность и адекватность используемой
архитектуры для решения определенных задач.
Дальнейшие исследования и развитие суперскалярной архитектуры привели к
разработке мультитредовой архитектуры процессоров, которые имеют более высокую
производительность [17].
Микропроцессоры Alpha 21264 и PentiumIII имеют однотредовую архитектуру с
использованием параллелизма уровня команд, выявляемый либо компилятором, либо
аппаратурой микропроцессора, либо их комбинацией. В этих микропроцессорах
параллелизм уровня тредов выявляется только статически – компилятором, динамически
это следать невозможно, так как необходимо просматривать большое количество команд,
а это ведёт к увеличению окна исполнения., что усложняет логические схемы управления
исполнением команд. А это может уменьшает тактовую частоту работы процессора.
Мультитредовые и мультискалярные процессоры решают эту проблему.
Главное отличие мультитредовой архитектуры в использовании совокупности
регистровых файлов процессора, для формирования которой используются транзисторы.
Эти регистры включают в себя счетчик команд, регистры состояния и рабочие регистры.
Эта архитектура избавляет от простоев процессора, возникающих из-за невозможности
выполнения следующей команды. В случае задержки происходит переключение на другой
регистровый файл, тем самым процессор продолжает вычисления с другим контекстом,
переходя к выполнению другого треда (процесса). Для каждого процесса(треда) есть свой
набор регистров. Процессор переключается на другой регистровый файл при наступлении
некоторого события(прерывания, обращение к оперативной памяти), либо принудительно.
Процессор использует n наборов регистров, поэтому при задержке первого из
процессов ему придётся ждать пока процессор снова переключится на тот же набор
регистров через n-1 тактов. Поэтому исполнение команд каждого треда замедляется в n
раз.
Формирования n тредов происходит на уровне компилятора при анализе исходного
кода на языке высокого уровня или исполняемого кода программы. Однако некоторые
зависимости при использовании регистров и ячеек памяти между тредами не
определяются компилятором, что требует разрешения этих зависимостей уже в ходе
исполнения тредов. Для этого в микропроцессоре есть специальная аппаратура условного
исполнения тредов, которая выполняет возврат с удалением полученных результатов в
случае обнаружения нарушения зависимостей между тредами, такими как запись по
вычисляемому адресу в одном треде в ту же самую ячейку памяти, из которой
выполняется чтение, которое должно следовать раньше записи, в другом треде.
Интерфейс между аппаратурой выполняющей исполнение отдельного треда
мультитредового процессора и общей для всех тредов аппаратурой может
устанавливаться по-разному:
после устройств выборки команд треда (каждый тред использует
собственные функциональные устройства, например, АЛУ, и ряд общих для всех тредов
функциональных устройств, например, для выполнения арифметических);
на уровне доступа к разделяемой памяти (для исполнения каждого треда
фактически выделяется функционально законченный процессор, для исполнения
независимых и слабо зависимых тредов, порождаемых либо одной программой, либо их
совокупностью).
Если мультитредовый процессор выполняет треды, порождённые одной
программой, то оценивают его производительность, если несколькими программи – о
пропускную способность.
69
В отличие от ветвей параллельной программы треды, найденные на основе потоков
управления, не имеют операторов взаимодействия между собой. В зависимых тредах
обмен осуществляется через доступ к разделяемым переменным аппаратными средствами.
2.1.9. Мультитредовая модель выполнения программы
Мультитредовая модель выполнения программы предполагает разбиение
программы на совокупность единиц обработки (тредов) с помощью программных и
аппаратных средств. Тред – часть программы, выполнению которой соответствует
непрерывная последовательность команд (полный цикл, часть цикла, базисный блок,
обращение к базисной функции и т.д.). Зависимости между тредами представляются в
виде графа управляющих зависимостей в котором вершинами являются треды, а дугами
задается порядок их выполнения. В результате выполнение программы рассматривается
как путь по таким графам.
Каждый вычислительный модуль выполняет только те команды, которые
принадлежат его треду, назначенному планировщиком. Общие значения регистров
копируются в каждый из ВМ. При получении от мультитредового процессора начального
значения программного счетчика каждый ВМ начинает исполнение своего треда. В
результате этого и организуется параллельность выполнения команд за один такт
мультитредового процессора.
Пример архитектуры мультитредового процессора представлен на рисунке 2.1.3.
Рисунок 2.1.3. Архитектура мультитредового процессора
Принятые обозначения: КК – кэш команд, ОЭ – обрабатывающий элемент, РФ –
регистровый файл.
Рассмотрим граф управляющих зависимостей , приведенный на рисунке 2.1.4 для
фрагмента программы с базисными блоками A, B, C, D, E. Пусть одна из возможных
последовательностей выполнения базисных блоков имеет вид
A11 , B11 , C11 , B21 , B31 , C21 , D11 , A12 , B12 , B22 , C12 , D12 , A13 , B13 , C13 , B23 , C23 , D13 , E
Верхние индексы соответствуют итерациям внешнего цикла, а нижние внутреннего.
A
B
C
D
E
F
F
F
F
F
Рисунок 2.5.4. Граф управляющих зависимостей фрагмента программы
Можно распределить единицы обработки, соответствующие разным итерациям на разные
процессорные элементы. Тогда первый процессорный элемент будет выполнять команды
70
базисных
блоков
A11 , B11 , C11 , B21 , B31 , C21 , D11 ,
второй
–
A12 , B12 , B22 , C12 , D12 ,
третий
–
A , B , C , B , C , D . В результате получим выполнение трех команд за такт.
В процессе выполнения должны оставаться связи по данным и по управлению
между командами, так как единицы обработки являются частями последовательного
потока команд. Последовательный порядок выполнения совокупности вычислительных
модулей с помощью организации циклической очереди вычислительных модулей
обеспечивается последовательным обходом графа управляющих зависимостей. Поэтому в
примере вычислительные модуль выполняют итерации по очереди, предшествуя друг
другу.
Мультитредовое выполнение обеспечивает такое же использование и произведение
значений как и при последовательном выполнении, когда область хранения переменных
рассматривается вычислительным модулем как набор регистров и памяти. При
использовании регистровой памяти можно создать отметку в маске создания, чтобы при
получении нового регистрового значения, оно посылалось через однонаправленный
кольцевой канал последующим тредам, т.е. в вычислительные модули, которые являются
логическими приемниками вычислительного модуля, выработавшего значение. Можно
синхронизировать потребление и производство используемого тредом значения из памяти
(команды загрузки), которое произведено (команда сохранения) в более раннем треде.
Загрузка в треде-приемнике не будет заканчивается до тех пор, пока в тредепредшественнике не будет сохранено требуемое значение. Если не известен результат
команды сохранения, используется консервативный или агрессивный подход.
При консервативном подходе ждут пока не будут уверенными, что команда
загрузки прочтет правильное значение. В результате этого возникает задержка
выполнения команд внутри треда до тех пор, пока треды-предшественники не завершили
операции записи в память.
Агрессивный подход используется в мультитредовых процессорах. В нём значения
из памяти записываются в регистры процессорного элемента предварительно, но только
если в последующем тред-предшественник не будет сохранять значения в ту же самую
ячейку памяти. Если проверка обнаруживает загрузку и сохранение, которые находятся в
противоречии, то более поздний тред должен быть прерван.
Мультитредовое выполнение включает средства подтверждения правильности
выполнения, так и средства исправления. Поэтому выполнение команд внутри тредов
разбивается на две группы:
- условное по управлению;
- условное по данным.
Тред, с неверными данными, отменяется и восстановливается правильное значение
данных. Аналогично, если следующий тред был предсказан неверно, то следующий тред
должен быть отменен и должна быть восстановлена правильная последовательность
тредов. В процессе предварительного выполнения тред вычисляет значения, которые
могут быть правильными или нет. Но в мультитредовом процессоре эти значения могут
использоваться также в ходе выполнения других тредов.
3
1
3
1
3
1
3
2
3
2
3
1
2.1.10. Аппаратные и программные средства, необходимые для
мультитредовой архитектуры
Тред - это часть программы, которая должна обеспечивать быстрый обход графа
управляющих зависимостей. Для этого блок-планировщик мультитредового процессора
собирает информацию о структуре потока управления программы, например, какие
единицы обработки могут быть преемниками любой единицы обработки в ГУЗ. Эта
информация хранится в специальном описателе единицы обработки. Описатели тредов
71
записывают либо внутри текста программы, либо в отдельном файле. Блок-планировщик
определяет порядок назначения тредов на выполнение вычислительным модулем.
Обработка регистровых значений происходит следующим образом. В результате
статического анализа ГУЗ компилятором формируется маска создания. Если треду
необходимо значение, он ждёт, пока это значение не будет произведено предыдущим
тредом или он находит это значение внутри локальной области памяти, переданной по
кольцу тредом-предшественником.
До запуска выполнения программы не представляется возможным определить
какие регистровые значения будут созданы в процессе вычисления, так как единица
обработки может содержать множество базисных блоков, зависящих от обрабатываемых
данных.
Последовательная семантика предполагает при завершении работы треды передачу
другим тредам его модификации регистра. Ожидание выполнения всех команд треда не
выгодно, так как это приводит к ожиданиям другими тредами значения, которое уже
является доступным.
С помощью компилятор определяется последняя команда в единице обработки,
которая модифицирует соответствующий регистр. Эта команда в дополнение к
выполнению определенной операции отправляет результат следующим тредам. Сам
процессорный элемент не может определить, какие команды выполняются на самом деле
назначенным ему тредом и его последнюю команду. Компилятор разбивая граф
управляющих зависимостей на единицы обработки обозначает границы обработки и узлы
передачи управления. Команда в одном из этих узлов передачи управления может быть
отмечена специальными условиями остановки так, чтобы при таких условиях
процессорный элемент мог определить остановку выполнения команды. Также можно
использовать специальные биты (пересылки и останова) для пересылки и завершения
треда.
Для того чтобы несколько команд выполнялось в одном такте используется
распределение тредов по ВМ. Когда тред ожидает получения значения или новых команд
процессорный элемент может выполнять бесполезные вычисления или ожидать.
Бесполезные вычисления появляются из-за использования неправильных данных или
неправильного предсказания. Чтобы уменьшить потери, связанные с бесполезными
тактами работы, следует повышать правильность предсказаний направления вычислений,
обеспечивая синхронизацию ВМ по данным, а также верно устанавливать факт
необходимости отмены.
Мультитредовая архитетура обладает многими преимуществами:
1) Общее количество команд, находящихся в обработке, значительно превышает
размер окна исполнения суперскалярного процессора и тактовая частота не лимитируется
размером окна исполнения, так как в рамках одного треда может выполняться
предсказание переходов, переименование регистров и динамическая подготовка команд к
исполнению.
2) Мультитредовый процессор даёт более дальние предсказания и большую
вероятность выбора правильного направления вычислений.
3) В отличие от суперскалярной архитектуры мультитредовая архитектура
обладает следующими свойствами: равное быстродействие выполнения регистровых
команд и команд доступа в память, эффективное использование множества
функциональных устройств, быстрое обслуживание прерываний, и возможность работы в
режиме жесткого реального времени, вычисления в микропроцессорах эффективно
совмещаются с обменами данными между ВМ.
4) При большом размере окна в мультитредовой реализации только несколько
команд должны быть рассмотрены в каждый момент времени на предмет выдачи
результатов. Для суперскалярных процессоров наличие широкого окна исполнения делает
72
трудоёмким контроль результатов выполнения всех команд в этом окне и увеличивает
число отложенных команд.
5) Суперскалярный процессор не рассматривает ГУЗ программы, поэтому каждый
переход должен выбираться наугад, что приводит к снижению точности предсказания и
производительности.
6) В мультитредовом процессоре реализации команды загрузки и записи могут
выполняться независимо, без знания последовательности выполнения команд загрузки и
записи в треде-приемнике или предшественнике, в суперскалярной архитектуре команды
загрузки и записи могут выполняться только последовательно с другими командами и
помещаются в буфер вместе с адресом доступа к памяти.
7) Отличие многопроцессорной системы от мультитредового процессора состоит в
том, что для многопроцессорной системы необходимо разделение программы на
процессы, зависимости между которыми известны, а мультитредовый процессор не
требует никакого предварительного знания о связях команд по управлению и данным.
8) Мультитредовая архитектура позволяет добиться более высоких значений
эффективности использования вычислительных модульных ресурсов процессора, чем
другие типы архитектур, так как компиляторы и аппаратура работают совместно для
статического и динамического поиска параллелизма в последовательных исходных
программах.
2.1.11. Специфика мультитредовых моделей распараллеливания
Рассмотрим мультитредовый микропроцессор Kin [22], который использует треды,
выявляемые путем анализа потоков данных программы. Этот микропроцессор строится на
функциональных блоках сообщающихся через FIFO очереди, элементы в таких очередях
выбираются по мере поступления. После обработки в функциональном блоке, результаты
обработки помещаются в выходную очередь. В итоге поток команд состоит из пакетов,
содержащих в себе теги и другую необходимую информацию для управления
функциональными блоками.
Базисный блок – это основной элемент микропроцессора Kin. В нём находится
последовательность команд преобразования данных в регистрах и памяти, которая
извлекается и декодируется устройством выборки команд. Далее в блоках
переименования регистров устраняются лишние зависимости по данным, потом команды
направляются в блок организации внеочередного исполнения. Затем команды поступают в
резервирующие станции, в которых они находятся пока не будут готовы операнды для
начала исполнения в функциональных блоках. В них происходит интерпретация
арифметических и логических команд, выполнение команд обращения к памяти.
Результаты исполнения отправляются в резервирующие станции, в блок внеочередного
исполнения команд или в блок предвыборки команд.
Блок предвыборки команд используется для предсказания переходов. Он
использует «жадную предвыборку команд»: после извлечения команды из кэш-памяти
декодированных команд он приписывает им динамический тег, обозначающий трассу,
которой принадлежит команда, при этом он может доставать команды из разных кэшстрок памяти как по направлению перехода, так и по направлению отсутствия перехода.
Поэтому при определении значения предиката команды перехода нужно удалить
результаты неверно предвыбранных команд и сами эти команды. Для этого используется
динамический тег, генерируемый в ходе исполнения команд перехода. Например, если
команда имела в теге трассу v, то предвыбранные команды одного направления получат
трассу v1, а другого – v8. Поэтому при каждом определении направления перехода можно
найти все ошибочные команды.
Мультитредовый процессор только исполняет треды, выбранные компилятором
или программистом. Их порядок определяет блок-планировщик. Мультитредовая
73
архитектура позволяет совместить команды обмена с вычислениями, например, тред,
обратившийся к сетевому адаптеру, будет ждать завершения обмена, в то время как
другие треды будут исполняться. Это свойство мультитредовых микропроцессоров делает
возможным построение из них массово параллельных систем. Таким образом,
мультитредовая архитектура служит следующим шагом в направлении развития методов
аппаратно-программного распараллеливания вычислений, давая при этом улучшение
результатов статического распараллеливания.
Второй способ распараллеливания характерен тем, что анализируется структура
решаемой задачи на уровне программных модулей и распределение программных
модулей между вычислителями строится на основе времён начала и окончания их
выполнения модулей, а также схем обмена данными между ними. Именно эта проблема
исследуется в дальнейшем в рассматриваемом курсе лекций.
Выполняемая программа разбивается на программные модули. Используются при
этом различные критерии, например, функциональную законченность модуля и т. д.
Наиболее приемлемым для рассматриваемого случая является обеспечение минимума
обмена информацией между модулями. Это связано с тем, что изучаемая в данном курсе
лекций ВС является критичной к объёмам передаваемой или получаемой информации.
Задача разбиения программы на модули является достаточно сложной, и обычно решается
разработчиком программ на интуитивном уровне в соответствии с возникающими
требованиями.
Рассмотрим пример реализации алгоритма умножения матриц в виде
параллельного алгоритма.
2.1.12. Вопросы к разделу 2.1
1. Какое различие существует между архитектурой ЭВМ и архитектурой ВС ?
2. Перечислите направления развития ВС.
3.Чем характерны архитектуры SISD, MISD, SIMD и MIMD ?
4. Охарактеризуйте суперскалярные ВМ.
5. Какие аппаратные и программные средства необходимы для мультитредовой
архитектуры ?
6. В чём специфика мультитредовых моделей распараллеливания ?
7. В чём сущность мультитредовой модели выполнения программы ?
2.2.Организация распараллеливания на уровне программных
модулей
2.2.1. Примеры организации вычислений на уровне программных модулей
При решении задач обработки информации возникает необходимость умножения
матриц большой размерности. При увеличении размерности прямоугольных матриц
существенно возрастает время выполнения операций над ними. Одним из решений этой
проблемы является использование распределённой вычислительной системы (РВС),
состоящей из нескольких однотипных вычислительных модулей (вычислителей, ВМ). Для
повышения эффективности использования РВС требуется создать алгоритм, позволяющий
распараллелить вычисления произведений соответствующих элементов исходных матриц
и добиться равномерной загрузки всех ВМ системы.
Даны две матрицы: A размерности NxK B размерности KxM, причём размерность
матриц существенно превышает количество ВМ n :
(2.2.1).
N>>n, K>>n, M>>n
Необходимо вычислить произведение матриц A  N  K   B  K  M   C  N  M  по
формуле
74
cij    aih bhj  , где i  1, N , j  1, M ,
K
(2.2.2)
h 1
используя все имеющиеся n ВМ системы.
Разбиение матриц, пересылка исходных данных. Поскольку предельная
размерность матриц, которые можно перемножить на РВС за один цикл пересылок, равна
количеству вычислителей, необходимо разбить исходные матрицы на части по n
элементов. В связи с особенностями формулы (2.2.2) произведём разбиение матрицы A
N 
по горизонтали (на   горизонтальных полос по n строк в каждой), а разбиение
n
M 
матрицы B – по вертикали (на   вертикальных полос по n столбцов в каждой).
n 
Перенумеруем вычислители, начиная с 1: v  1, n . Для начала работы алгоритма
необходимо разместить в памяти каждого ВМ соответствующую его номеру строку
первой горизонтальной полосы матрицы A и соответствующий его номеру столбец
первой вертикальной полосы матрицы B . В дальнейшем будут осуществляться
последовательный проход по вертикальным полосам матрицы B (со сменой начального
передающего вычислителя  н. ,  н.  1, n ) и по горизонтальным полосам матрицы A .
Пересылка рабочей строки. Рассмотрим отдельно взятые горизонтальную и
N 
вертикальную полосы соответствующих матриц. Обозначим их Ah , h  1,   и
n
M 
Bw , w  1,   , соответственно (в каждой полосе содержится n элементов, зависящих от
n
её ориентации в матрице – строк или столбцов). Смещения начальных элементов
рассматриваемых полос от начала матриц будут равны n   h  1 и n   w  1 ,
соответственно.
Каждый вычислитель должен произвести вычисление одного элемента
результирующей матрицы (ЭРМ): номер строки этого элемента соответствует номеру
передающего вычислителя  , а номер столбца – номеру данного ВМ v . Для этого
необходимо поместить в память данного ВМ текущую строку горизонтальной полосы Ah
матрицы A . В памяти одного ВМ эта строка уже присутствует – назовём этот
вычислитель передающим, поскольку именно он будет производить пересылку текущей
строки всем остальным ВМ. Содержимое памяти передающего ВМ показано на рис.2.2.1.
75
Рисунок 2.2.1. Содержимое памяти передающего ВМ
В памяти вычислителя, не являющегося передающим, будут храниться две строки –
строка, соответствующая его номеру ( Ah v ), и строка, соответствующая номеру
передающего ВМ ( Ah   ). Последняя из двух является рабочей строкой для вычисления
ЭРМ.
Назовём часть результирующей матрицы C , соответствующую полосам Ah , Bw ,
матричным блоком (МБ). Каждый МБ состоит из n ЭРМ. В пределах одного МБ за
полный цикл расчёта каждый вычислитель РВС один раз является передающим.
Вычисление элемента результирующей матрицы. Вычисляемый ЭРМ представляет
собой строку размерности n . Все ячейки этой строки вычисляются параллельно, с
использованием всех вычислителей РВС. Частичные произведения из формулы (2.2.2)
суммируются во внутренней промежуточной переменной c , затем соответствующим
ячейкам ЭРМ последовательно присваиваются полученные значения.
Переход к следующей строке внутри текущего МБ. Переход к следующему МБ.
После вычисления очередного ЭРМ, не являющегося последним, в текущем МБ,
передающим становится следующий по порядку вычислитель, номер вычисляемого ЭРМ
также увеличивается на единицу.
Если очередной ЭРМ является последним в текущем МБ, производится переход к
следующему МБ, соответствующему полосам Ah , Bw1 результирующей матрицы C . Если
все МБ текущей горизонтальной полосы матрицы A обработаны, производится переход к
МБ, соответствующему первой вертикальной полосе матрицы B и следующей по порядку
горизонтальной полосе матрицы A , т. е. к МБ, соответствующему полосам Ah1 , B1 .
76
Рисунок. 2. Упрощённая блок-схема алгоритма умножения матриц большой размерности с
использованием РВС
Если все МБ обработаны, то алгоритм завершается: в памяти каждого ВМ хранятся
те столбцы результирующей матрицы C , номера которых можно определить по формуле
M 
rv     l  v, l  1, n  1 ,
(2.2.3)
n
где rv – номера столбцов результирующей матрицы C , хранящихся в v -ом ВМ.
Упрощённая блок-схема рассмотренного алгоритма представлена на рисунке 2.2.2.
Оценка вычислительной сложности алгоритма. Для оценки вычислительной
сложности алгоритма введём следующие обозначения:
t p  S  – среднее время пересылки S ячеек матрицы из области памяти, в которой
записаны исходные данные, в память текущего вычислителя или из памяти текущего
вычислителя в область памяти, где записывается результирующая матрица;
77
t – среднее время перемножения двух ячеек исходных матриц (частичные
произведения в формуле (2.2.2));
t  – среднее время сложения двух частичных произведений по формуле (2.2.2).
Все времена измеряются в относительных единицах, например, в процессорных
тактах.
Длительность пересылки исходных данных для одного ВМ оценивается как
1
TВМ
 2t p  K  ,
(2.2.4)
длительность пересылки рабочей строки для одного ВМ –
2
TВМ
 tp K  ,
(2.2.5)
длительность вычисления ЭРМ для одного ВМ –
3
TВМ
 Kt   K 1 t ,
(2.2.6)
длительность пересылки результатов для одного ВМ –
 M 
4
(2.2.7)
TВМ
 tp  N     .
  n 
Итак, суммарная длительность выполнения алгоритма умножения матриц большой
размерности, удовлетворяющих условию (2.2.1), с использованием РВС, в соответствии с
соотношениями (2.2.4) – (2.2.7) оценивается как
4
j
T  n   TВМ
 3nt p  K   t p  N  M   Kt  Kt ,
(2.2.8)
j 1
в то время как суммарная длительность перемножения матриц малой размерности
на одном ВМ равна
TММР 1  2t p  N  M    N  M  t   K 1  Mt .
(2.2.9)
Для определённости примем, что размеры матриц одного порядка (обозначим этот
характерный размер матриц N * ). Сопоставляя выражения (2.2.8) и (2.2.9), можно прийти к
выводу, что рассмотренный алгоритм имеет большую вычислительную сложность
организации пересылок данных (примерно в 3nN * раз), но значительно ускоряет
собственно умножение (примерно в N * раз). Из этого следует, что алгоритм даёт больший
выигрыш во времени при реализации в РВС с общей памятью.
Предложенный простой алгоритм умножения матриц большой размерности с
использованием РВС позволяет распараллелить вычисления и добиться равномерно
высокой загрузки всех ВМ системы. Данный алгоритм эффективен для РВС из n
вычислителей, если время пересылки данных не превосходит времени вычисления
значения одной ячейки результирующей матрицы C , умноженного на утроенное
количество ВМ в системе: t p  3nt .
При решении различных задач физики и математики возникает необходимость
решения систем линейных алгебраических уравнений (СЛАУ). При этом число
уравнений в системах может быть велико и однопроцессорный компьютер либо не может
их решить из-за нехватки памяти, либо их решение занимает очень много времени,
поэтому возникает необходимость разработки параллельных алгоритмов решения СЛАУ.
Традиционно методы решения делятся на точные (дающие точный ответ без учета
ошибок округления) и итерационные (точное решение есть предел бесконечной
последовательности приближений).
Пусть A - заданная матрица невырожденная симметричная положительно
определенная (n*n), b – известный (n*1)-вектор, а y – неизвестный (n*1)-вектор.
Рассмотрим систему линейных алгебраических уравнений (СЛАУ)
Ay=b
(2.2.10)
78
Итерационные методы решения системы (2.2.10) позволяют строить
последовательность приближений (итераций)
Если эта последовательность имеет
предел, то он называется решением системы (2.2.10).
Очередное приближение строится с помощью рекуррентной формулы
(2.2.11)
где k - номер итерации. Преимущественно используется простейшая рекуррентная
формула
(2.2.12)
где B - квадратная nxn матрица, а h - n-мерный вектор. Для организации счета по
такой формуле требуется задание начального приближения . Вид матрицы B и вектора h
определяет тот или иной итерационный метод.
В общем случае, итерационный метод сходится, если ||B|| < 1. Отсюда следует, что
сходимость имеет место, если:

все собственные числа матрицы B по модулю меньше единицы;

имеет место диагональное преобладание элементов матрицы B .
Все итерационные методы строятся по одной схеме: система (2.2.10) преобразуется
к виду
(2.2.13)
где
,и
- легко обращаемая матрица: единичная, диагональная или
треугольная. В этом случае из (3) без труда получается выражение
h,
(2.2.14)
которое далее используется в качестве рекуррентной формулы (2.2.12).
Рассмотрим параллельный алгоритм решения СЛАУ методом простой итерации.
Приближенные решения (итерации) системы линейных уравнений последовательно
находятся по формуле:
N
yk(i)1  yk(i )  t ( ai , j yk(i )  f k(i ) ), i  1, 2,..., N
(2.2.15)
j 1
Для решения этой задачи на параллельной системе исходную матрицу
коэффициентов А разрезаем на p1 горизонтальных полосы по строкам, где p1 - количество
процессоров в системе. Аналогично, горизонтальными полосами разрезаются вектор b
(правая часть) и вектора y0 (начальное приближение), yk (текущее приближение) и yk+1
(следующее
приближение).
Полосы
последовательно
распределяются
по
соответствующим процессорам системы. Каждый процессор системы вычисляет "свое"
подмножество корней. Поэтому после нахождения приближенных значений корней на
очередном шаге итерации на каждом процессоре проверяется выполнение следующего
условия для "своих" подмножеств корней:
yk(i)1  yk( i )  e
(2.2.16)
Условием завершения работы каждого процесса является безусловное выполнение
условия (2.2.16) на всех процессорах. И если условие (2.2.16) не выполнилось хотя бы на
одном процессоре, то вычисление корней продолжается и каждый процесс передает всем
остальным процессам полученную итерацию своих корней. Тем самым вектор y
полностью восстанавливается в каждом процессе для выполнения операции его
умножения на матрицу коэффициентов на следующем шаге итерации.
Параллельный алгоритм решения СЛАУ методом сопряженных направлений.
Данный алгоритм оптимизирован для запуска на многопроцессорной системе, где
каждый процессор соединен с каждым.
Решение СЛАУ (2.2.10) эквивалентно отысканию минимума квадратичной формы
79
1 T
y Ay  bT y
(2.2.17)
2
Распараллеливание
метода
сопряженных
направлений
сводится
к
распараллеливанию вычисления указанных скалярных произведений и матричновекторных произведений.
Положим для простоты записи, что порядок n системы (2.2.10) кратен количеству
процессоров N в системе, т.е. что величина n кратна величине N , так что p=m/N.
Основные этапы алгоритма:
1.
Вычисление частей скалярного произведения (ak+1, xk) и после пересылки
частей получение на каждом процессоре всего произведения
Q( y ) 
Рисунок 2.2.2. Распределенние данных между ВМ на первом этапе алгоритма
2.
Затем на каждом процессоре вычисляется
где k=0,…,n.
3.
Параллельно на всех процессорах системы вычисляем соответствующие
компоненты произведений Ax1, Aen+1 , а также соответствующие части скалярных
произведений.
80
Рисунок 2.2.3. Распределение данных на третьем этапе
4.
Каждый из процессоров системы посылает одному из процессоров
вычисленные суммы. На этой основе указанный процессор формирует вектор X* и
сравнивает полученное решение с предыдущим, если разность между ними мала, то
вычисления заканчиваются.
Рисунок 2.2.4. Формирование вектора Х*
Использование итерационных методов совместно с предобусловливанием по
Булееву [33, 34] является одним из наиболее быстродействующих по времени и
количеству итераций методом в настоящее время. Он относится к семейству методов
вариационно-итерационного типа и применим для решения знаконеопределенных СЛАУ с
81
несимметричной в общем случае матрицей, для которой неизвестны спектральные
свойства.
Идея предобусловливания заключается в преобразовании исходной задачи
(решение системы линейных уравнений) таким образом, чтобы матрица
предобусловленной системы имела лучшие спектральные свойства и полученная система
решалась более легко. Под этим понимается, что алгоритм требует меньше
вычислительных ресурсов за меньшее число итераций.
Для ускорения процесса сходимости и уменьшения числа итераций может использо
ваться процедура предобусловливания по методу неполной факторизации Булеева,
формулы которой получаются из формул явного метода Булеева исключением
итерационных членов [33, 34].
Алгоритм предобусловливания (решение систем вида Ky = pi или Kz = s , K A )
состоит из двух этапов: прямого и обратного хода. На первом шаге вычисляются
прогоночные коэффициенты, формулы для определения которых имеют рекуррентный
вид (где Θ – параметр компенсации 0 ≤ Θ < 1):
(2.2.17)
А затем решение { y i j } находится по формуле
(2.2.18)
Отметим, что предобусловливание по методу Холесского или LU-факторизации
для задач вида (2.2.10) менее эффективно, чем предобусловливание по Булееву [34].
Пусть требуется решить систему двух связанных линейных дифференциальных
уравнений в единичном квадрате ((x, y) (0,1)x(0,1), G – граница) с граничными условиями
третьего рода
(2.2.19)
где
(i=1,2) - достаточно гладкие функции от x и y , а
константы.
Результаты[35] численного эксперимента по решению системы (2.2.19) на кластере
показали, что использование предобусловливателя более чем на порядок сокращает
временные затраты на решение системы линейных алгебраических уравнений. На рис.
2.2.5 представлен график зависимости времени вычисления от числа используемых
процессорных элементов.
Знание алгоритма формирования номеров ВМ и последовательности значений,
которые каждый должен передать, позволяет создать эффективный коммуникационный
процесс, учитывающий специфику производимых вычислений.
Анализ представленного примера позволяет акцентировать внимание на ряде
обстоятельств. Во-первых, проблема ввода-вывода. Если данные вводить в каждый из n1
ВМ, то время ввода будет превышать по порядку величины время вычисления. Поэтому
распределение данных по ВМ должно быть частью параллельного алгоритма. Во всяком
случае, пропускная способность ввода/вывода данных должна быть сбалансирована со
скоростью вычислений.
82
Рисунок 2.2.5. Зависимость времени счета от числа процессоров
Во-вторых, достаточно сложно автоматически выявить структуру и организацию
межмодульных обменов. Поэтому автоматическое распараллеливание последовательных
программ может и не привести к созданию эффективных параллельных программ. Но
приведенные выше параллельные реализации метода умножения матриц и итерационного
алгоритма решения СЛАУ показывают, к достижению какого результата надо стремиться
при построении параллельных программ.
Метод простой итерации (метод Якоби)
Пусть имеется система линейных алгебраических уравнений (СЛАУ) вида (2.2.10),
где А — заданная невырожденная матрица nxn с отличными от нуля диагональными
элементами, b — заданный (nx1) вектор, а х — неизвестный (nx1) вектор.
Представим матрицу A в виде:
A = A + D + A+
где D – диагональная матрица с диагональными членами матрицы A:
D = diag  A =  a11 0
... 0 
(2.2.20)


0
a 22 ... 0 


0
0
... a nn 

A − – часть матрицы A, лежащая ниже центральной диагонали; A + – часть матрицы
A, лежащая выше центральной диагонали.
Тогда
A + D + A+ x = b




Dx =  A  + A+ x + b
Запишем итерационный метод в виде:
Dx k+1 = A + A+ x k + b , k = 0,1,2,... .
Отсюда получаем:
x k+1 =  D 1 A + A+ x k + D 1b , k = 0,1,2,... .
(2.2.21)
Итерационная формула:
i 1
n

1 
(2.2.22)
xik+1 =  bi   aij x kj   aij x kj  , i = 1,2,...,n
aij 
j=1
j=i+1

где хiк+1 — значение компоненты i вектора x на (k+1)-ой итерации.
83
Метод Якоби заключается в разрешении каждого из уравнений системы
относительно одной из компонент вектора. Таким образом, из первого уравнения системы
выражается х1 и его значение принимается за х1к+1. Из второго уравнения определяется х2
и его значение принимается за х2к+1 и т. д. Переменные в правой части этих соотношений
при этом полагаются равными их значениям на предыдущей итерации.
Теоремы о сходимости метода:
Теорема 1. Если матрица А имеет строгое диагональное преобладание, то итерации
метода Якоби сходятся при любом начальном приближении Х0
Теорема 2. Если матрица А симметрична и положительно определена, то итерации
метода Якоби сходятся при любом начальном приближении x0 тогда и только тогда, когда
матрица (D+D-A) положительно определена.
Матрица А называется матрицей со строим диагональным преобладанием, если для
всех
имеет место неравенство
Критерий завершения процесса вычислений :
(2.2.23)
где xk – приближенное значение решения на k-м шаге численного метода.
Параллельный алгоритм метода простой итерации
Метод простой итерации описывает следующая система уравнений:
x1k+1 = f1 x1,k  x2,k  ..., xnk 
x2k+1



= f1x   x   ..., x   
k
1,

k
2,
...
k
n

xnk+1 = f1 x1,k  x2,k  ..., xnk 
Значения компонента вектора х на каждой итерации не зависят друг от друга, а
зависят только от значений вектра, вычисленных на предыдущих итерациях.
Схема параллельного алгоритма итерационного решения СЛАУ приведена на
рис.2.2.6. Рассмотрим основные этапы алгоритма.
На первом шаге определяется количество координат вектора, вычисляемых на
каждом ВМ. Для просторы записи положим, что число строк и столбцов матрицы А
кратно количеству процессоров в системе, т. е. если m — количество строк матрицы А, а
m
N — количество процессоров в системе, то p= N .
Значению вектора Х на предыдущей итерации (Xold) присваивается значение
вектора начального приближения Х0.
На следующем шаге происходит распределение по ВМ компонентов матриц
А, b, Xold.
Следующие операции производятся параллельно на всех ВМ системы:
 на ВМ1 вычисляются компоненты X r+11... X r+p1 ;

+1
на ВМ2 вычисляются компоненты X pr++11... X r2p
;
 …
+1
 на ВМ n вычисляются компоненты X  N 1 pr++11... X rNp
.
Вычисленные в каждом ВМ компоненты передаются остальным ВМ.
84
Рисунок 2.2.6. Схема алгоритма решения СЛАУ методом Якоби
Далее в соответствии в формулой (2.2.23) на одном из ВМ производится проверка
критерия завершения процесса вычислений. При достижении требуемой точности:
max | X r+1i X ri|< ε , где r — номер итерации, i — номер компоненты вектора Х,
решение СЛАУ найдено (вектор Хr+1), работа алгоритма завершается.
85
В противном случае, значению Xold присваивается значение Хr+1, и происходит
следующая итерация.
Представление схемы алгоритма в виде графа приведено на рис.2.2.7.
На данном графе оператор «1» выполняет определение числа координат вектора,
вычисляемых на каждом из ВМ, оператор «3» выполяет рассылку необходимых
компонент всем ВМ. Операторы «р1»... «рN» и «s1» … «sN» (вычисление компонент
вектора по формуле (2.2.20) и рассылка вычисленных значений другим ВМ) выполняются
параллельно на всех ВМ.
Операторы «r1» - «rm» организуют цикл для проверки выполнения критерия
завершения вычисления. Они выполяются последовательно на одном из ВМ.
1
2
3
p
1
p
2
s
1
s
2
...
p
N
...
s
N
4
r
1
...
r
2
r
m
6
7
Рисунок 2.2.7. Представление схемы алгоритма в виде графа
2.2.2. Решение системы линейных уравнений методом Гаусса с помощью ВС
типов «решётка» и «линейка»
Рассмотрим широко известный алгоритм рещения СЛАУ отличающийся простотой
реализации. Пусть дана система линейных уравнений (2.2.24):
a11 x1 + a12х2 +…+ a1nхn = a1,n+1
a21 x1 + a22 х2 +…+ a2nхn = a2,n+1
…
an1 x1 + an2 x2 +…+ ann xn = an,n+1
(2.2.24)
86
Решение системы уравнений по компактной схеме [25]
последовательном определении хn, xn-1, ..., x1 из системы уравнений:
заключается
в
x1 + c12х2 +…+ c1nхn =c1,n+1
c12 х2 +…+ a1nхn = a2,n+2
…
xn = cn,n+1
Эта система получается как результат разложения исходной матрицы на
треугольные матрицы согласно формулам (2.2.25):
j 1
сij  ( aij   bik * ckj ) / bii ,1  i  n,1  j  n  1, i  j
(2.2.25)
k 1
j 1
b ij  aij   bik * ckj ,1  i, j  n, i  j,
k 1
После вычислений «прямого хода» метода Гаусса получается матрица:
b11c12 c13 ...c1,n c1,n 1
b21b22 c23...c2,n c2,n 1
............................
bn ,1bn , 2 bn ,3 ...bn ,n cn ,n 1
Из рекуррентных соотношений следует, что любой (i,j)-элемент матрицы получается
как разность между исходным элементом аij и суммой парных произведений ранее
определенных значений bik, находящихся в рассматриваемой строке слева, и
соответствующих значений сkj, расположенных в рассматриваемом столбце сверху от
вычисляемого значения. При определении значений сij необходимо также выполнить деление
на значение bii. Использование метода без выбора ведущего элемента предполагает, что
все bii, i = 1, ... , n, отличны от нуля, и деление на bii не приводит к потере точности.
Граф информационных зависимостей алгоритма получения треугольных матриц 4х4
показан на рисунке 2.2.8.
a12
a11
a22
a21
a32
a31
a42
a41
a13
C12
a14
C13
a23
a24
C22
a33
C23
C32
C33
a34
a43
C42
a44
C43
a15
C14
C15
a25
C24
C25
a35
C34
C35
a45
C44
C45
Рисунок 2.2.8. ГУЗ алгоритма получения треугольных матриц для п = 4
Значения xi ,
i = n, n - 1, ... , 1, вычисляются по формуле:
b i
xi  ci ,n 1   ci ,n k 1 * xn k 1
k 1
Значение хn находим при
разложении матрицы. Последующие значения хi
формируются как разность сi,n+1 и суммы парных произведений предыдущих вычисленных
значений хп,..., xi-1 на соответствующие значения сi,n, ... , c i , i - 1 .
Граф информационных зависимостей для п = 4 показан на рисунке 2.2.9.
87
c15
C12
C13
C14
C23
C24
X1
c25
X2
c35
C34
X3
X4
2.2.9. Граф информационных зависимостей для п = 4
Поиск неизвестных по элементам верхней треугольной матрицы осуществляется с
помощью обратного хода алгоритма Гаусса.
2.2.3. Исполнение алгоритма Гаусса на «решётке» n*n ВM
Рассмотрим два характерных случая выполнения алгоритма Гаусса: выполнение на ВС,
содержащей n2 ВМ (решетке п*п.) и ВС, состоящей из n ВМ (линейке), где n – число
неизвестных системы уравнений.
Пусть ВС с п2 ВМ имеет граф межмодульных связей в котором, каждая вершина с
индексами (i,j) графа информационных связей, приведенного на
рисунке 2.2.8,
отображается в соответствующий ВМij, i = 1, ... , п, j = 2, ... , п + 1. Информационным
связям между операторами алгоритма соответствуют передачи данных по межмодульным
линиям связи.
Будем полагать, что для программирования передачи данных в передающем ВМ
используется оператор send x (а), где х принимает значение u(up), d(down), l(left), r(right) в
зависимости от того, какому соседу предназначены для передачи данные а. Аналогично, в
принимающем ВМ программирование выборки из входных очередей выполняется
посредством оператора receiver x (b), где х принимает значения u, d, l, r в зависимости от
того, от какой ВМ идёт приём данных. Принятый элемент данных - b.
Предположим, что в каждый ВМij. начиная с j = 3 по j = п + 1 передан соответствующий элемент aij исходной матрицы коэффициентов системы уравнений, а ВМi2
содержат по два элемента аi1 и ai2.
Вычисления начинаются в ВМ12, который определяет значение 1/b11 = 1/а11 и
посылает его правому соседу ВМ13, после чего тот вычисляет с12 = а12/b11 и посылает
нижнему соседу ВМ22. Прием данных стартует вычисления в ВМ13 и ВМ22.
ВМ13 передает полученное значение 1/b11 своему правому соседу ВМ14 и вычисляет
с13 = а13/b11. Вычисленное значение с13 передается нижнему соседу ВМ23.
ВМ22, получив с12, пересылает это значение нижнему соседнему ВМ32, затем посылает
хранящееся в нем значение b21 = а21 правому соседнему ВМ23, а также вычисляет 1/b22 =
1/(a22- b21с12). Далее значение 1/b22 передается в ВМ23.
После описанных выше действий стартуют ВМ32, ВМ23 и ВМ14. Таким образом
вычисления ВМ начинаются при приёме данных. Прямой ход заканчивается в ВМn,n+1.
Обратный ход инициируется ВМn,n+1, который сразу по завершении прямого хода
имеет вычисленное значение хn, он передаёт его верхнему соседу ВМn-1,n+1 . Получив это
значение, ВМn-1,n+1 передает его верхнему соседнему ВМn-2,n+1, а также использует,
совместно с полученным от соседнего ВМn-1,n
значением сn-1,n , для вычисления
xn-l = cn-1,n+l - cn-l,nxn. Далее хп-1 передается в ВМn-2,п+1. Обратный ход завершается
определением х1 в ВМ1,n+1.
Представленный способ выполнения параллельных вычислений по алгоритму Гаусса
позволяет получить следующую оценку времени реализации [26]: Тn*n = 5n-4 при общем
88
числе операций порядка n3 / 3, что дает оценку ускорения параллельных вычислений
порядка п2 /15.
2.2.4. Исполнение алгоритма Гаусса на «линейке», состоящей из n ВМ
Теперь рассмотрим выполнение этого алгоритма на ВС, имеющей граф
межмодульных связей цепочку (линейку) из п вершин. В ВМ будут выполняться все
вычисления элементов i-й строки, i= 1, ... ,n.
BM1 передает последовательность вычисленных значений с12, с13 ,..., с1n, c1,n+1
соседнему ВМ2. Получив очередное значение, ВМi , i = 2, ..., п - 1, передает это значение
своему соседу ВМi+1 и производит требуемое преобразование размещенной в нем i-й
строки. После приема ВМi, i = 2, ..., п - 1, значений, выработанных во всех ВМj, j<i, ВМi
приступает к передаче вычисленных в нем значений сi,i+1, ..., сi,n+1. Прямой ход
завершается вычислением в ВМn значения сп,п+1 = хп.
ВМ1 стартует вычисления, а остальные ВМ начинают работать, когда до них доходят
вычисленные величины. ВМ приступает к передаче выработанных в нем значений после
приема всех предназначенных ему значений. Для определения момента наступления этого
события может быть использован счетчик числа принятых значений либо значения могут
сопровождаться номерами. Поведение каждого ВМ зависит от числа принятых им значений.
Обратный ход инициируется ВМn и состоит в передаче ВМi принимаемых ими
значений хп ,..., xi+1 B ВМi-1 и вычислении хi также передаваемом в ВМi-1 , i = n-1, ... , 2.
Вычисления завершаются после приема ВМ1 значений хп, ..., х2 и вычисления значения х1.
Оценка времени параллельной реализации [26] Тn = (2n2 + 7n - 6) / 2, что при
общем числе операций порядка п3/3 дает порядок ускорения параллельных вычис-лений
2п/ 3.
В представленных выше параллельных реализациях алгоритма для решения задачи в
системе из N ВМ формируется подсистема, состоящая либо из п, N > п, либо из п2 ВМ, N>
п2, где п – порядок системы уравнений. Однако такие структуры не всегда можно
выделить в качестве подграфа даже на кубических графах размерности два и более, не
говоря о произвольных графах межмодульных связей. Так как в реальных системах всегда
есть вероятность отказа совокупности ВМ и межмодульных связей. Поэтому важна
организация эффективных параллельных вычислений на подсистемах с произвольными
связными графами межмодульных связей.
Один из возможных вариантов организации таких вычислений заключается в
построении покрывающего корневого дерева на произвольном связном графе с корнем в
произвольной вершине. Нумерация вершин дерева может происходить по следующему
алгоритму.
1. Присвоим корневой вершине номер ноль. Вычислим к := 1. Переход на шаг 2.
2. Поиск пронумерованной вершины ВМi , i= {0, 1, ... ,n} с номером i, наибольшим из
числа присвоенных номеров. Корнем дерева является i, не все вершины которого имеют
номера. Если такой вершины нет, переход на шаг 5, иначе вычислим j:= i и переходим на
шаг 3.
3. Построим множества А, включающее соседние с ВМj вершины, не имеющие
номеров. Переходим на шаг 4.
4. Если А пусто, переход на шаг 2, иначе выбор из А одной вершины и присвоение
ей номера k. Присваиваем j := k; k := k + 1. Переходим на шаг 3.
5. Конец.
На рис 2.2.10 показан результат нумерации на различных деревьях.
89
1
3
0
2
0
4
1
0
1
4
3
2
3
3
4
Рисунок 2.2.10. Построение покрывающего корневого дерева
Вычислительный процесс получает элементы данных, поступающие в ВМ по
нисходящему дереву, и выдает вычисляемые в нем элементы данных в восходящее дерево.
Для этого используются операторы receive и send соответственно. При этом
вычислительный процесс идентифицирует поступающие элементы данных либо по
счетчику, как это было представлено выше при реализации алгоритма Гаусса, либо по
поступающей вместе с данными метке.
1
3
0
0
2
4
1
0
2
1
3
4
3
3
4
Рисунок 2.2.11. Нисходящие к корню, покрывающие ориентированные деревья
1
0
0
3
2
1
4
0
1
4
3
2
3
3
4
Рисунок 2.2.12. Восходящие к корню, покрывающие ориентированные деревья
В процессе обмена данными происходит перенос элементов данных, поступающих в
восходящее дерево, в корневой ВМ. Из корневого ВМ элементы данных передаются по
нисходящему дереву во все ВМ. При такой схеме в каждый ВМ поступают одинаковые
последовательности элементов данных.
Можно создать эффективный коммуникационный процесс, учитывая порядок
нумерации ВМ и данные, которые они должны передавать.
Анализ представленного примера показывает несколько проблем:
1. Если данные вводить в каждый из n ВМ, то время ввода будет превышать на
порядок время вычисления. Поэтому распределение данных по ВМ должно быть частью
параллельного алгоритма. И пропускная способность ввода/вывода данных должна быть
согласована со скоростью вычислений.
2. Выявление структуры и организации межмодульных обменов – сложно
поддающийся автоматизации процесс. Поэтому автоматическое распараллеливание
последовательных программ может и не привести к созданию эффективных параллельных
программ..
90
2.2.5. Показатели эффективности параллельных алгоритмов
Для оценки эффективности работы параллельных алгоритмов используется ряд
показателей, таких как коэффициент накладных расходов, коэффициент ускорения и
коэффициент эффективности p-программы.
1) Коэффициент накладных расходов определяется по формуле
ε = t/T ,
где t – время, расходуемое ВС на организацию и реализацию всех обменов информацией
между вычислительными модуляи, Т – время, требующееся на выполнение
арифметических и логических операций при реализации параллельного алгоритма.
Рассмотрим использование этого показателя на примере умножения матриц (см.
раздел 2.2.1).
В каждом вычислителе выполняется K*]M/n[ -умножений, (K-1)*]M/n[ - сложений.
При достаточно большом значении K можно считать, что на каждый принятый
элемент матрицы А приходится ρ операций сложения и умножения:
ρ = ]M/n[
Пусть tп – время пересылки одного элемента матрицы, tс – время сложения двух
чисел, tу – время умножения двух чисел.
Тогда эффективность можно определить в виде:
ε = tп / ρ(tу + tс) = e / ρ , где e = tп / (tу + tс).
Из этого соотношения видно, что максимум накладных расходов будет, когда ρ=1
или n=M. Величина ρ=1 информирует о минимально допустимом размере матриц, при
котором ещё целесообразно вычисление задачи на n вычислителях. С другой стороны, при
фиксированном n, увеличение размера матриц приводит к росту ρ, следовательно, к
уменьшению накладных расходов. Ясно, что чем больше размеры матриц (чем больше
размеры вычислений), тем выше эффективность параллельного алгоритма, т.е. ε→0, ρ→∞.
2) Коэффициент ускорения определяется по соотношению
χ = τ1 /τn ,
(2.2.26)
где τ1 – время выполнения алгоритма (решения задачи) на одном ВМ, τn – время
выполнения параллельного алгоритма (решения той же задачи) в системе из N
вычислительных модулей.
Как известно, что одна и та же задача может решатся различными по
эффективности алгоритмами, поэтому вводится дополнительное соотношение,
учитывающее это обстоятельство:
χ’ = τ1’ /τn ,
(2.2.27)
где τ1’ – время выполнения последовательного наилучшего алгоритма, τn – величина,
взятая из соотношения (2.2.26).
Для определения коэффициента ускорения часто используют закон Амдаля,
который используется, если известны более подробные характеристики ВС и
выполняемых алгоритмов:
 А ≤ k / (δ+(1 – δ)/N),
91
где N – количество ВМ входящих в ВС, δ – относительная доля операций параллельной
программы, выполненных последовательно, 0 ≤ δ ≤ 1. δ =1 – программа относительно
последовательна и δ= 0 – программа относительно параллельна. k – корректирующий
коэффициент 0 ≤ k ≤ 1. Он определяет качество параллельной системы, т.е. система
характеризуется временными издержками, связанными с настройкой структуры системы,
синхронизацией ветвей параллельной программы и временными издержками, связанными
с обменом информацией между ВМ.
3) Для определения качества параллельной программы используется коэффициент
её эффективности:
E = χ / N,
(2.2.28)
где χ - коэффициент ускорения, определённый по формуле, N – число вычислительных
модулей в ВС.
Если χ ≤ N, то E ≤ 1. Если параллельный алгоритм обеспечивает максимальное
ускорение, то χ = N и E = 1. Основной целью распараллеливания сложных задач является
достижение равенства
max χ = N. Аналогичные соотношения получим при
использовании χ’.
Основные причины, препятствующие получению этого равенства:
1. время, расходуемое на синхронизацию параллельных ветвей процессов и на
обмен информацией между ними, а также на конфликты памяти, обусловленные,
например, её общедоступностью или наоборот её распределённостью.
2. несбалансированность
нагрузки
вычислителей
и/или
невозможность
построения p-алгоритма с числом ветвей, равным числу вычислителей ВС.
2.2.6. Понятие о сложных задачах
Следует иметь в виду, что сложность задачи определяет возможные пределы
ускорения ее решения за счет параллелизма обработки. Так бессмысленно уменьшать за
счет параллельной обработки время решения простой задачи. Поэтому параллельные
системы применяют при решении сложных задач. Это создает проблемы с
масштабированием и переносимостью параллельных программ и оценкой эффективности
параллельных вычислений. Сложную задачу нельзя выполнить на одном ВМ в силу,
например, недостаточного объема основной памяти. Использование внешней памяти ведет к
изменению алгоритма и неадекватному сравнению производительностью одного ВМ и
параллельной системы из многих ВМ.
Для построения понятия о сложных задачах представим коэффициент накладных
расходов в развёрнутом виде:
ε(v, N) = t(v, N) / T(v, N),
где v – количество операций, которое необходимо выполнить при решении задач на
ВС.
N – число вычислителей, N ≥ 2.
t – время, затраченное на синхронизацию параллельных ветвей алгоритма, на
настройку программируемой структуры системы, на реализацию обмена между
вычислителями.
T – время вычислений.
Как было ранее установлено, что ε(v, n)→0 при v→∞, поэтому представляют
несомненный интерес большие значения v. Опытным путём была установлена
зависимость
v ≥ N*10k,
(2.2.29)
где k – эмпирический коэффициент, который ≥ 1.
92
Оценена зависимость k от быстродействия каналов связи. Таким образом, можно
сделать вывод, что объём операции v должен на несколько порядков превышать число
вычислителей N. В этом случае достигается эффективное функционирование ВС.
Задачи, для которых выполняется (2.2.29) называются сложными (системными,
трудоёмкими, с большим объёмом вычислений), следовательно, задача тем сложнее, чем
больше объём вычислений v. Когда не выполняется соотношение (2.2.29), о задачи
называются простыми и должны решаться на одном ВМ.
2.2.7. Вопросы к разделу 2.2
1. Какое различие между распараллеливанием на уровне команд и на уровне
программных модулей ?
2. Какие существуют схемы распараллеливания алгоритма умножения матриц?
3. Чем отличаются схемы распараллеливания алгоритма решения системы
линейных уравнений на «линейке» и на «решётке»?
4. Охарактеризуйте нисходящие и восходящие к корню, покрывающие
ориентированные деревья.
5. Каким способом была оценена эффективность алгоритма умножения матриц?
6. В чём специфика применения закона Амдаля?
7. В чём сущность оценки сложности программ?
93
ГЛАВА 3. НАДЕЖНОСТЬ И ЖИВУЧЕСТЬ
ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМ
3.1. Основные задачи создания отказоустойчивых систем
При создании новых систем для обработки информации перед разработчиками
стоят две основные задачи:
а) достижение высокой производительности;
б) обеспечение высокой надежности.
Эти задачи противоречивы, и в каждом конкретном случае необходимо искать
компромисс. Путь решения первой задачи – повышение быстродействия отдельных
элементов ИС и максимальное распараллеливание процесса обработки данных. При
решении второй задачи возможны два основных подхода:
1. Предотвращение
отказов
системы
реализуется
путем
повышения
технологического уровня изготовления компонентов ИС, минимизации ошибок
разработчиков, программистов, операторов. Улучшению надежностных характеристик
отдельных подсистем способствует входной контроль, повышение степени интеграции
элементов, эффективные методы рассеивания тепловой энергии. Однако данный подход
наталкивается на естественные ограничения технического и экономического характера.
2. Создание отказоустойчивых систем. При этом допускается возникновение
отказов, но используются эффективные методы устранения их последствий.
Отказоустойчивость – свойство архитектуры ИС, обеспечивающее выполнение
заданных функций в случаях, когда в аппаратных и программных средствах системы
возникают отказы.
Кроме того, при построении ВС стараются следовать следующим трем принципам:
1) массовый параллелизм (параллельность выполнения большого числа операций);
2)программируемость
(автоматическая
перестраиваемость
или
реконфигурируемость) структуры;
3) конструктивная однородность.
Остановимся на таком важном факторе, как возможность перестраиваемости
структуры и архитектуры вычислительной системы. Это связано с тем, что
отказоустойчивость и повышение производительности вычислительных средств в
значительной степени зависят от возможности использования перестраиваемых либо
комбинированных
структур
и
архитектур.
Благодаря
такой
динамичной
перестраиваемости, происходит адаптация вычислительной системы к внутренним и
внешним условиям функционирования (сбоям, отказам, решаемым задачам и т.д.).
3.1.1 Вопросы к разделу 3.1
1.Что понимается под отказом системы?
2. Дать определение отказоустойчивых систем.
3. Как влияет улучшение надежностных характеристик отдельных компонентов ВС?
4. Какие существуют эффективные методы устранения отказов в ВС?
5. Причины появления отказов в системе.
94
3.2. Классификация типов отказоустойчивости сложных систем и
ее критерии
Сложные технические системы в процессе эксплуатации подвергаются
детерминированным и стохастическим внешним воздействиям, приводящим к различного
вида повреждениям элементов и связей: износу, поломке, засорению, выгоранию, обрыву
и т.п. Накапливаясь, повреждения приводят к отказу - нарушению работоспособности
объекта, которое определяется перечнем заданных параметров и допустимыми пределами
их изменения. Нарушение работоспособности может произойти при выходе значения хотя
бы одного параметра за пределы, установленные требованиями нормативно-технической
документации. Признаки, позволяющие установить факт такого нарушения, являются
критериями отказа. Для сложных технических систем этот критерий отказоустойчивости
не всегда показателен, поскольку нарушение работоспособности отдельного элемента
может не сказаться на работоспособности всей системы в целом. В сложных системах
возможно большое количество мест повреждений. Вероятность ее безотказной работы
может быть оценена статистически в результате проведения серии экспериментов
(рисунок 3.2.1), связывающих отказоустойчивость с количеством возникших
повреждений, при этом:
р – статистическая оценка вероятности отказа системы;
n – количество отказавших элементов и/или связей между ними;
n1 – максимальное количество отказавших элементов и/или связей, при которых
вероятность отказа равна нулю;
n2 – минимальное количество отказавших элементов и/или связей, при которых
вероятность отказа равна единице.
Полученное семейство экспериментальных точек условно разбито на три зоны:
зона I: 0 < n < n1; p = 0 – повреждений не больше, чем n1; система абсолютно
работоспособна;
зона II: n1 < n < n2; 0 < p < 1 – повреждений больше, чем n1, но меньше, чем n2;
система сохраняет работоспособность лишь при некотором наборе этих повреждений;
- зона III: n2 < n; p = 1 – повреждений больше, чем n2 - 1; система неработоспособна
при любом их наборе.
-
Рисунок 3.2.1 Результаты экспериментальной статистической оценки вероятности
отказа сложной технической системы
Очевидно, что отказоустойчивость системы зависит от значений n1 и n2 и тем
выше, чем дольше сохраняется нулевая вероятность отказа (т.е., чем больше n1), и чем
больше наклонена к оси абсцисс прямая, аппроксимирующая экспериментальные точки в
зоне II, (т.е. чем больше (n2 - n1)).
В зависимости от наличия и протяженности вдоль оси n этих зон, можно
классифицировать четыре типа отказоустойчивости системы (см. таблицу 3.2.1).
95
Таблица 3.2.1
№ Тип
п/п отказоустойчивости
Графическая
аппроксимация
Значения
границ
зон
Характеристика
5.
Абсолютно
неустойчива
n1 = 0;
n2 = 1
Первое же любое
повреждение
приводит к отказу
2.
Негарантированная
отказоустойчивость
n1 = 0;
n2 > 1
Отказоустойчивость
пропорциональна р
при n >0
3.
Гарантированная
отказоустойчивость I
n1 > 0;
n2 - n1 = 1
Система
отказоустойчива до
n< n1.
При n > n1 первое же
любое повреждение
приводит к отказу
4.
Гарантированная
отказоустойчивость II
n1 > 0;
n2 - n1 > 1
Система
отказоустойчива до
n< n1.
Приведенные типы отказоустойчивости представляют собой условную
аппроксимацию экспериментальных точек прямыми.
Первый тип по своим показателям соответствует абсолютно неустойчивой и в этом
смысле ненадежной системе, первое же любое повреждение любого элемента (или связи)
приводит к отказу. Естественно, такая система не нуждается в критериях оценки
отказоустойчивости.
Второй тип соответствует системе с негарантированной отказоустойчивостью, т.к.
первое же любое повреждение может привести к отказу.
Третий тип отказоустойчивости также является ненадежным с точки зрения
эксплуатационных характеристик системы, поскольку после некоторого количества
повреждений вероятность отказа скачком превращается из 0 в 1.
Четвертый тип сочетает в себе свойства второго и третьего.
По способу реализации отказоустойчивость подразделяется на активную и
пассивную.
Активная отказоустойчивость базируется на отдельно выделенных процессах
обнаружения отказа, локализации отказа и реконфигурации системы. Отказы
обнаруживаются средствами контроля, локализуются при помощи средств диагностики и
устраняются автоматической реконфигурацией системы. Последняя заключается в
перестройке структуры системы таким образом, чтобы ее отказавшие компоненты были
устранены от участия в работе.
Пассивная отказоустойчивость заключается в способности системы не потерять
свои функциональные свойства в случае отказа отдельных элементов. В таких случаях
96
говорят, что отказ маскируется системой. Пассивная отказоустойчивость связана с
увеличением количества аппаратуры в несколько раз; она применяется обычно тогда,
когда недопустимы даже кратковременные перерывы в работе ВС, а также для
обеспечения отказоустойчивости важнейших блоков или устройств системы.
Применение активной отказоустойчивости характеризуется более экономным
расходом аппаратных средств, однако связано с некоторыми потерями времени при
восстановлении работы системы после отказа (иногда возможны потери некоторой части
данных). Активная отказоустойчивость реализуема только в многопроцессорных
системах. В то же время применение пассивной отказоустойчивости гарантирует
практически бесперебойную работу ВС и сохранение всей информации. Эти
обстоятельства
определяют
области
применения
активной
и
пассивной
отказоустойчивости.
Введение отказоустойчивости является одним из способов повышения надежности
ВС. Вопрос о построении и применении отказоустойчивых систем возникает тогда, когда
другие пути повышения надежности не обеспечивают требуемого ее уровня по
техническим или экономическим причинам.
Отказоустойчивость системы обеспечивается введением избыточности, т.е.
созданием определенных запасов или резервов. В отказоустойчивых ВС может быть
использована избыточность параметрическая, временная, алгоритмическая и структурная.
Параметрическая избыточность выражается в облегчении режимов работы
элементов и узлов аппаратуры с целью повышения их надежности. Однако, для правильно
спроектированной системы эксплуатационные и другие параметры выбраны близкими к
оптимальным, поэтому существенного увеличения надежности за счет параметрической
избыточности, достигнуто быть не может.
Временная избыточность заключается в наличии дополнительного времени для
решения задачи, с тем, чтобы в случае возникновения сбоев можно было исправлять их
путем повторной обработки данных. Временная избыточность создает предпосылки для
реализации ресурсов по повышению отказоустойчивости, имеющихся в данной системе
(реконфигурация, повторение вычислений), поскольку для этого требуется
дополнительное время.
Алгоритмическая избыточность заключается в применении таких алгоритмов,
которые обеспечивают удовлетворительные результаты в случае наличия или
возникновения ошибок в процессе обработки информации. Алгоритмическая
избыточность предполагает наличие временной избыточности и является средством ее
реализации. Например, свойствами избыточных алгоритмов обладают итерационные
алгоритмы, обеспечивающие сходимость при больших случайных отклонениях
промежуточных результатов.
Структурная избыточность является наиболее эффективным видом избыточности.
Она выражается в наличии дополнительных элементов, узлов, устройств в структуре
системы, предназначенных для автоматической замены отказавших компонентов.
Структура пассивно отказоустойчивых систем основана либо на мажоритарном
принципе, либо на резервировании с контролем. Количество резервной и дополнительной
аппаратуры в таких системах превышает количество основной аппаратуры.
Структура активно отказоустойчивых систем может быть различной. Активная
отказоустойчивость может быть применена в многопроцессорных системах c общей
памятью, общей шиной, кольцевой, иерархической или другой структурой.
3.2.1 Вопросы к разделу 3.2
1. Какие типы отказоустойчивости существуют в сложных систем?
2. Назовите критерии отказоустойчивости сложных систем.
3. Чем отличается абсолютная отказоустойчивость от негарантированной?
97
4. Чем отличается гарантированная отказоустойчивость I от гарантированной
отказоустойчивости II?
5. Дайте определение активной отказоустойчивости сложных систем.
6. Дайте определение пассивной отказоустойчивости сложных систем.
7. Что такое параметрическая избыточность?
8. Чем отличается параметрическая избыточность от временной?
9. В чем сущность алгоритмической избыточности?
3.3. Способы обеспечения отказоустойчивого функционирования
ВС
Ниже обзорно рассмотрены средства устранения последствий отказов и сбоев, а
также основные способы восстановления процесса обработки данных. В общем же
случае процесс функционирования отказоустойчивой ВС может быть представлен
схемой на рисунке 3.3.1.
Важным с точки зрения функционирования ВС является повышение
показателей надежности отдельного узла (вычислительного модуля (ВМ)) ВС, это
достигается блокированием воздействий отказавших компонентов и их оперативной
заменой:
- отказ процессора – использование многопроцессорных конфигураций;
- отказ памяти – использование кодов с обнаружением и исправлением ошибок;
- отказ дисков – применение RAID технологий, а также горячей замены (без
прерывания функционирования компьютера) отказавших дисков и контроллеров;
- отказ питания и охлаждения – использование резервных блоков питания и
блоков вентиляторов, источников бесперебойного питания, а также горячей их
замены.
Работоспособное
состояние системы
Возникновение
ошибки
Локализация
ошибки
Восстановление
вычислительного
процесса
Восстановление
потерянной
информации
Реконфигурация
системы
Рисунок 3.3.1. Последовательность функционирования отказоустойчивой ВС
Объединение таких элементов в ВС создает следующий уровень обеспечения
надежности – взаимное контролирование узлами друг друга с целью парирования
ошибочных действий персонала, адекватной реакции на изменение внешней среды и
т.д.
Коэффициент готовности отдельного ВМ без применения средств
блокирования последствия отказов обычно 0,99. Это составляет около 4 дней в году.
Объединение ВМ в систему и применение вышеперечисленных мер позволяет довести
коэффициент готовности до 0,9999, что сводит простой ВС к нескольким минутам в
год.
Основные подходы к обеспечению отказоустойчивости
Обеспечение отказоустойчивости ВС включает решение следующих проблем:
1) обнаружение сбоя или отказа программно-аппаратных средств;
2) диагностирование сбоя или отказа и устранение влияния отказа;
98
3) восстановление работоспособности путем использования для продолжения
функционирования признанных работоспособными процессоров и протекающих на
них прикладных программ либо путем перезапуска общесистемных и прикладных
программ на реконфигурированной ВС.
Каждая из вышеперечисленных проблем может решаться разными методами,
причем программно-аппаратные затраты на ее решение зависят от интервала времени,
допустимого по условиям эксплуатации ВС, от момента сбоя или отказа до момента
восстановления работоспособности.
3.3.1. Диагностическое тестирование ВС
Тестирование ВС может строиться как на основе тестов самопроверки ВМ, так
и на базе тестовой взаимной проверки ВМ друг друга или использования комбинации
этих подходов. Рассмотрим подход к тестированию на основе взаимной проверки ВМ
друг друга.
Итак, будем полагать, что каждый ВМ может запустить по линку
диагностический тест в соседним с ним ВМ путем передачи в него теста и удаленного
запуска тестирования с возвращением результата тестирования. Если ВМ,
производящий тестирование, исправен, то он делает правильное заключение о
работоспособности подвергшегося тестированию ВМ. Если неисправный ВМ
тестирует соседний ВМ, то результат тестирования – произвольный. Соседний ВМ
может быть признан как исправным, так и неисправным.
При взаимном тестировании ВМ может образовывать подсистемы ВМ,
имеющих одно и то же заключение об исправности друг друга. Тестирование
инициируется в одном или нескольких ВМ независимо друг от друга по собственному
таймеру или каким-либо иным способом. Пусть ВМi тестирует соседний ВМk и
признает его исправным, затем ВМk тестирует ВМi. Если ВМk признает ВМi
исправным, то они образуют подсистему из двух ВМ, имеющих одинаковое
представление об исправности друг друга. Далее каждый из включённых в подсистему
ВМ пытается включить в нее все соседние с ним ВМ. При этом несколько независимо
строящихся подсистем могут объединяться в одну, если ВМ, входящие в них, имеют
одинаковое представление об исправности друг друга. При этом в ходе тестирования
ВМ подсистемы обмениваются сообщениями, на основании которых подсчитывается
число ВМ, включенных в подсистему. В предположении одновременного
существования в ВС не более чем m неисправных ВМ, все ВМ, имеющие заключение
друг о друге как об исправном ВМ, при числе ВМ подсистемы, превышающем m
признаются исправными. Эта подсистема образует диагностическое ядро,
используемое для тестирования остальных ВМ системы.
Выделение диагностического ядра ускоряет и упрощает тестирование ВС. ВМ
диагностического ядра уже не нуждаются во взаимопроверке, а просто делают
заключение об исправности остальных ВМ.
3.3.2. Способы и средства устранения последствий ошибок и отказов в ВС
Как известно, простейшим способом устранения ошибок является повторение
вычислений. Однако он позволяет устранить только ошибки, вызванные сбоями, и
требует значительных затрат машинного времени. Поэтому в практике используют два
основных способа устранения последствий отказов и ошибок в работе ВС:
- маскирование ошибочных действий;
- реконфигурация системы.
Классификация способов устранения последствий отказов и ошибок приведены
на рисунке 3.3.2.
99
Способы и средства устранения последствий отказов и ошибок
Маскирование
Реконфигурация
Корректирующие
коды
Замещение
Логика с
переплетениями
Дублирование
Схемы с
голосованием
Постепенная
деградация
Рисунок 3.3.2. Классификация
последствий ошибок и отказов
способов
и
средств
устранения
Суть первого способа состоит в том, что избыточная информация скрывает
действие ошибочной информации за счет особенностей схемных решений и
организации процесса обработки данных. При этом используются средства устранения
последствий ошибок – средства маскирования, которые делятся по принципу действия
на следующие группы:
- корректирующие коды (коды Хэмминга, итеративные коды, AN-коды);
- логика с переплетениями;
- схемы с голосованием (используется нечетное число блоков, выполняющих
одни и те же вычислительные операции, и большинством «голосов» определяется
правильный набор выходных данных).
Соответственно возможные альтернативы использования этих методов
определяются тем, что предпочтительнее:
1) затратить больше ресурсов и медленнее, чем максимально возможно,
выполнять программу, выявляя сбои и отказы,
2) выполнять программу с максимально возможной скоростью (без избыточных
обменов и ВМ) и проводить через некоторые промежутки времени тестирование на
предмет выявления отказов.
Выбор между этими альтернативами следует производить с учетом того, что
ресурсы, затрачиваемые на обнаружение сбоев и отказов, могут быть использованы
для ускорения параллельного выполнения программы, что, в свою очередь, ведет к
образованию временной избыточности. Последняя может быть также использована
для повышения отказоустойчивости. Например, временная избыточность позволяет
повторять вычисления и сравнивать результаты, что выявляет сбои при исполнении
программы.
Реконфигурация системы заключается в изменении состава средств обработки
информации или способа их взаимодействия. Реконфигурация производится после
выявления отказа. Этот способ устранения последствий ошибок и отказов включает:
- статическую реконфигурацию;
- динамическую реконфигурацию.
Статическая реконфигурация системы осуществляется путем отключения
отказавших компонентов. При этом система делится на две части: активную,
участвующую в работе, и пассивную, охватывающую
неработоспособные
компоненты системы и отключенные в ходе реконфигурации.
100
Динамическая реконфигурация по принципу проведения делится на следующие
виды:
- замещение (поддержка запасом);
- дублирование;
- постепенная
деградация
системы
способностей).
(снижение
функциональных
3.3.3. Способы восстановления отказоустойчивых ВС
После реконфигурации для продолжения нормальной работы системы
необходимо ее восстановить. Восстановление системы происходит на двух уровнях
(см. рисунок 3.3.3).
Способы восстановления
Аппаратный уровень
Программный уровень
Автоматическое
Повторение операции
Ремонт (ручное
восстановление)
Возвращение к
контрольной точке
Повторное выполнение
программы
Рисунок 3.3.3. Классификация способов восстановления ИС.
Аппаратный уровень. Здесь для восстановления отказавших компонентов ИС
используют два способа:
- автоматическое восстановление, реализуемое путем дополнительной
реконфигурации системы. При этом предполагается, что в системе имеется ряд
запасных блоков, благодаря которым она возвращается в работоспособное состояние.
Производительность системы либо сохраняется, либо несколько снижается;
- ремонт (восстановление вручную). В этом случае отказавший блок выводится
из системы, и она либо продолжает работать с меньшей производительностью, либо
приостанавливается до возвращения отремонтированного блока в активную часть ВС.
Программный уровень. Здесь осуществляется восстановление информации о
состоянии системы, необходимой для продолжения ее работы. В зависимости от
нарушений в работе системы (от количества ошибочной информации) можно
выделить следующие способы восстановления:
- повторение операции на различных уровнях (команд или микрокоманд).
Повторное выполнение некоторых операций может дать правильный результат, если
связанная с ними ошибка является случайной или временной (ошибка исчезает в
процессе восстановления);
- возвращение к контрольной точке. Контрольной точкой называется
некоторый этап процесса обработки информации, для которого зафиксированы (в
запоминающем устройстве) промежуточные результаты и информация о состоянии
системы, позволяющая возобновить обработку данных. При обнаружении ошибки
система возвращается к контрольной точке, предшествующей моменту возникновения
отказа, и продолжает свою работу, используя данную точку в качестве исходной;
101
- повторное выполнение программы. При этом способе восстановления все
незавершенные (до возникновения отказа) программы выполняются с самого начала.
Это необходимо, когда в системе разрушено такое количество информации, что
восстановление путем повторного выполнения отдельных операций или участков
программ невозможно. Данный способ применяется в случаях:
а) если последствия отказа успели отразиться на большей части системы;
б) если возможно восстановление только части вычислительных процессов;
в) если продолжение работы системы при использовании других способов
восстановления сопряжено с трудностями и большими затратами времени.
Рассмотрим более детально использования так называемых контрольных
точек (КТ). Исполнение программы состоит в выполнении следующей
последовательности действий:
1) запуск программы с текущей контрольной точки (первая КТ – исходное
состояние программы и обрабатываемых данных) и выполнение вычислений до
следующей контрольной точки;
2) диагностическое тестирование ВС: при выявлении отказа – формирование
работоспособной конфигурации программно-аппаратных ресурсов и повторение
вычислений с предшествующей КТ, при отсутствии отказа – сохранение новой КТ в
качестве текущей и запуск программы с текущей КТ.
Применяются следующие типы контрольных точек:
1. Локальная контрольная точка. Процессы периодически сохраняют КТ. Этот
тип КТ устойчив к сбоям, но не к отказам процессора или диска. В этом случае
сохранённая КТ становится недоступной.
2. Зеркальная КТ. Процессы периодически сохраняют КТ на своих локальных
дисках и копии этих КТ на соседних дисках. Этот тип КТ устойчив к одиночным
неисправностям.
3. Устойчивая КТ. Процессы периодически сохраняют КТ на дисках RAID,
которые устойчивы к отдельным совокупностям отказов.
При исполнении параллельных программ между ВМ передаются сообщения,
что обусловливает необходимость специальным образом подходить к выбору
положения контрольных точек ВМ.
Чтобы повысить эффективность параллельных вычислений, необходимо
исключить возможность множественных откатов, требующих сохранения большого
количества контрольных точек и большого объема повторных вычислений. Это может
быть достигнуто использованием системных контрольных точек, сохраняющих
состояние всех ВМ после взаимодействия между ними.
Автоматическое (без участия разработчика параллельной программы)
формирование системных контрольных точек представляет сложную проблему.
Формирование
системных
КТ
при
разработке
программы
усложняет
программирование, но позволяет повысить эффективность за счет постановки КТ в
местах, требующих сохранения минимально возможного объема данных, и с учетом
особенностей обменов данными между ВМ.
В настоящее время не существует общепринятого подхода к формированию
системных КТ. В случае конкретных ВС могут быть применены системы
программирования, автоматизирующие расстановку КТ, исходя из специфики
исполняемых прикладных программ.
3.3.4 Вопросы к разделу 3.3
1. Дайте определение коэффициента готовности отдельного вычислительного
модуля.
2. Каким образом осуществляется диагностическое тестирование ВС?
102
3. Какие существуют способы устранения последствий ошибок и отказов ВС?
4. Дайте определение статической реконфигурации ВС.
5. Дайте определение динамической реконфигурации ВС.
6. Классифицируйте способы устранения ошибок и отказов ВС.
7. Какие контрольные точки существуют с целью борьбы со сбоями и отказами?
3.4. Построение живучих ВС на основе экспоненциальнонадежностного подхода
Cовременные высокопроизводительные средства обработки информации – это
распределённые вычислительные системы, системы с массовым параллелизмом.
Число
функционально-конструктивных
элементов
обработки
информации
(элементарных машин или процессоров) в таких вычислительных системах уже сейчас
имеет порядок 106. Это обстоятельство даёт основание специалистам в области
анализа эффективности (производительности, надёжности, живучести и техникоэкономической эффективности) средств обработки информации называть
распределённые ВС большемасштабными.
Полнота воплощения принципов модели коллектива вычислителей определяет
архитектурную гибкость ВС. Cовременные распределённые ВС обладают свойством
масштабируемости, а архитектурно гибкие их представители характеризуются и
программируемой структурой.
Принципы, положенные в основу построения ВС (особенно систем с
программируемой структурой), требуют нетрадиционного подхода к решению
проблемы их надёжности. Под надёжностью ВС будем понимать свойство системы
сохранять заданный уровень производительности путём программной настройки её
структуры и программной организации функционального взаимодействия между её
ресурсами.
Вычислительные системы рассчитываются на работу в моно- и
мультипрограммных режимах. В первом случае для решения любой задачи отводятся
все ресурсы ВС, а во втором – лишь часть из них. Ясно, что монопрограммный режим
целесообразен при решении на ВС сложных или трудоёмких задач. К последним
относят задачи, для решения которых требуется выполнить достаточно большое число
операций.
Пусть N – число элементарных машин в распределённой вычислительной
системе (с программируемой структурой). Будем говорить, что система находится в
состоянии k  E0N , E0N  {0,1,..., N  1}, если в ней имеется k исправных ВМ.
Теоретически и экспериментально показано, что производительность системы, при
k  E0N , равна (k )  Ak k , где  – показатель производительности элементарной
машины; Ak – некоторый коэффициент.
Линейная зависимость производительности ВС от числа исправных ВМ –
следствие применения методики крупноблочного распараллеливания сложных задач.
Суть методики – требование однородно расчленять задачу на крупные блокиподзадачи, между которыми существует слабая связность. Говоря иначе, методика
предписывает организацию таких однородных параллельных ветвей алгоритма
решения сложной задачи, общее число операций в которых много больше числа
операций обмена информацией между ветвями.
Вычислительные системы, компонуются, в общем случае, из неабсолютно
надёжных элементарных машин. Пусть  – интенсивность потока отказов в любой
из N машин.
Отказы, возникающие в вычислительной системе, устраняются при помощи
процедуры
восстановления.
Последняя
предусматривает
и
контроль
103
функционирования ВС, и локализацию неисправных ВМ, и их ремонт или замену на
исправные машины, например, из резерва. Будем считать, что эта процедура
реализуется при помощи восстанавливающей системы, состоящей из m устройств,
1 < m < N.
После отказа ВМ либо поступает на обслуживание в любое свободное
восстанавливающее устройство (ВУ), либо (если таковых нет) ставится в очередь на
восстановление. Считается, что в каждый момент времени любое из m ВУ может быть
либо свободным, либо занятым восстановлением не более одного ВМ. Далее, пусть  –
интенсивность восстановления отказавших ВМ одним ВУ. Из сказанного следует, что
в системе допустимы переходы из состояния k  E0N как в состояние k-1, так и в
состояние k+1, (kN).
В теории потенциальной надёжности ВС введены системы со структурной
избыточностью, которые являются обобщением систем с резервом. Вычислительные
системы со структурной избыточностью с позиций архитектуры и способов обработки
информации не являются специальным классом систем в ряду: конвейерные,
матричные, мультипроцессорные ВС, ВС с программируемой структурой и т.д.
Вычислительная система со структурной избыточностью, в сущности, есть
виртуальная ВС или, точнее, программно настроенная конфигурация, в которой:
1) выделены основная подсистема (вычислительное ядро) из n элементарных
машин и подсистемы, подчинённые основной и составляющие избыточность из (N-n)
машин ( n  0, n  E0N );
2) основная подсистема предназначена для решения сложных задач,
представленных параллельными программами из n ветвей, а любая подчинённая
подсистема – для решения фоновых задач;
3) функции отказавшего ВМ основной подсистемы может взять на себя любой
исправный ВМ любой подчинённой подсистемы;
4) производительность (при изменении состояния k = 0, 1, 2, ... , N)
подчиняется следующему закону:
(k )  An  (k  n)  (n, ),
где An – коэффициент; Ω(k) – производительность (точнее, один из показателей
производительности) элементарной машины;  ( n, ) – неубывающая функция от n и
 (как правило,  (n, )  n ).
ВС со структурной избыточностью выглядит для пользователей как (виртуальная)
система из n ВМ. Эта же ВС с позиций проектировщиков и эксплуатационников
выглядит как система с высоким уровнем надежности, который достигается за счёт (N
– n) избыточных машин. Величина (N – n) структурной избыточности в таких системах
изменяется программно, но для заданной сложной задачи (для выбранной области
применения ВС) она постоянна. Значение n (и, следовательно, N – n) выбирается из
требований обеспечения производительности и надёжности ВС.
Параллельная программа решения задачи имеет фиксированный объём
информационной избыточности, которая используется для того, чтобы исправный ВМ
структурной избыточности мог взять на себя функции отказавшего ВМ основной
подсистемы. Информационная и структурная избыточности не уменьшают времени
решения задачи, а увеличивают надёжность работы ВС в целом (как аппаратурнопрограммного комплекса).
104
3.4.1. Показатели надежности ВС
Для количественного анализа работы вычислительных систем используется
набор показателей надежности. Главное требование, которое предъявляется к набору,
это обеспечение полноты характеристики качества функционирования ВС.
Следовательно, должны быть показатели, характеризующие производительность ВС и
в текущий момент времени, и на промежутке времени, а также показатели,
позволяющие оценить способность системы к восстановлению заданного уровня
производительности после отказа её отдельных машин. Среди показателей надёжности
ВС, безусловно, должны быть такие, которые характеризуют поведение систем и на
начальном этапе функционирования (в переходном режиме), и при длительной
эксплуатации (в стационарном режиме).
Показатели
надёжности
устанавливают
взаимосвязь
между
производительностью и собственно надёжностью ВС. Следовательно, показатели
надёжности позволяют, во-первых, подобрать такой состав вновь компонуемой ВС,
при котором обеспечиваются заданные уровни и производительности, и надёжности,
во-вторых, проанализировать качество работы существующей ВС и оценить её
возможности по решению задач. Последнее важно знать и при организации
контрольно-профилактических и диагностических работ в ВС и при организации
прохождения задач пользователей.
Показатели надёжности работы ВС позволяют получить следующую
информацию:
1) с какой вероятностью задача пользователя будет решена, если в момент её
поступления производительность ВС не менее требуемой; говоря другими словами,
сможет ли пользователь успеть решить свою задачу до отказа системы;
2) как быстро можно ожидать восстановления требуемого для пользователя
уровня производительности, если в момент поступления задачи производительность
ВС низка;
3) будет ли ВС иметь необходимую производительность в момент поступления
задачи в систему.
4) сколь быстро можно ожидать восстановления требуемого уровня
производительности в условиях, когда ВС уже длительно эксплуатируется;
5) будет ли система иметь необходимую производительность в любой момент
поступления задачи, если она уже достаточно долго находится в эксплуатации.
3.4.2. Методика расчета показателей надежности ВС
К методике расчёта показателей качества работы вычислительных систем
предъявляются следующие требования:
1) приемлемость методики к большемасштабным и масштабируемым
вычислительным системам;
2) адекватность стохастических моделей функционирования ВС реальному
процессу их работы;
3) единообразие методов и приёмов исследования функционирования ВС как в
переходном, так и в стационарном режимах;
4) простота численного анализа функционирования ВС при произвольном
числе;
5) возможность выявления общих количественных закономерностей по
производительности и надёжности функционирования ВС, которые отражают
достигнутый и перспективный уровни технологии вычислительной техники.
105
При расчёте показателей надёжности за основу берётся стохастическая модель
функционирования ВС, представленная на рисунке 3.4.1. В случае отказа одного или
нескольких ВМ основной подсистемы и после их локализации (диагностики ВС)
требуется реконфигурация ВС в целом. С помощью реконфигуратора в пределах ВС
порождается новая конфигурация основной подсистемы из n исправных ВМ.
Вычислительная система,
N ЭМ
Подсистема отказавших
ЭМ

Основная подсистема, n ЭМ
Восстанавливающая
система, m ВУ
Реконфигуратор ВС
Структурная избыточность,
(N - n) ЭМ

Рисунок 3.4.1. Модель функционирования ВС со структурной избыточностью
Применение классического способа расчёта математических ожиданий времени
безотказной работы θ и времени восстановления Т для большемасштабных ВС
наталкивается на серьёзные трудности, связанные с трудоёмкими и сложными
вычислениями функций надежности R(t) и восстановимости U (t). Вычисления
функций R(t) и U (t) основываются в основном на традиционные стохастические
модели теории массового обслуживания и методы приближённых вычислений.
Трудоёмкость такого расчета растёт с ростом числа машин в системе, и, кроме того, на
этом пути не удаётся получить аналитические формулы для отыскания числовых
значений  и Т.
Для распределенных вычислительных систем θ и Т удобно рассчитывать
«частотным» методом, который достаточно прост и приводит к результатам, хорошо
согласующимся с более точными вычислениями. Можно показать, что среднее время
безотказной работы ВС при n ≠ N и при n=N соответственно равно:
N
1 j 1 l 1
1
 



n ;
j  n 1 j l  n l 
N .
Среднее время восстановления ВС при n ≠ 1 и при n = 1 определяется
выражениями:
1 n1 l  n 1 1 n1 l 
1
T    
T
 l 1 l j 1 j l  j l
,
;
где
 i – средний поток числа восстанавливаемых ВМ, λ-1 – среднее время безотказной
работы одного ВМ,  -1 – среднее время восстановления отказавшего ВМ одним
106
восстанавливающим устройством, m- количество устройств в системе. Также можно
показать, что коэффициент готовности большемасштабной ВС:
m
n 1
 m  1  
S  1 
e

j 0    j !
j
3.4.3. Живучесть ВС
Живучесть является более ёмким понятием, чем надёжность ВС. Живучесть
определяет способность вычислительной системы (достигаемая программной
организацией структуры и функционального воздействия между её компонентами) в
любой момент функционирования использовать суммарную производительность всех
исправных ресурсов для решения задач.
Живучесть ВС должна достигаться при решении задач, представленных
программами с любым допустимым числом параллельных ветвей или, что то же самое,
с любым рангом r, 1 ≤ r ≤ N, где N – общее число BМ в системе. Исключением не
должны быть задачи с переменным рангом. Живучесть должна обеспечиваться и в
монопрограммном, и в мультипрограммных режимах работы ВС. При
монопрограммном режиме для определённости будем полагать, что переменный ранг
задачи ограничен снизу n и сверху N. Величина n одновременно является и нижней
границей числа работоспособных BМ (считается, что при числе отказавших BМ,
равном N-n+1, имеет место полный отказ ВС). При мультипрограммировании сумма
рангов одновременно решаемых задач не превышает N.
Живучесть ВС рассматривается в двух аспектах: потенциальном и
структурном. При анализе потенциальной живучести ВС особенности структуры или
сети межмашинных связей в прямом виде не учитываются, и считается, что в системе
обеспечиваются возможности по достижению необходимой связности исправных ВМ.
При изучении структурной живучести ВС, учитываются топологический вид сети
межмашинных связей и надёжностные характеристики компонентов этой сети.
Программы, при реализации которых автоматически устанавливается число
параллельных ветвей, равное числу работоспособных машин в текущий момент
времени, относятся к адаптирующимся. Теоретически и экспериментально
установлено, что для достаточно широкого круга задач могут быть составлены
эффективные параллельные программы, обладающие способностью адаптации к
составу работоспособных вычислительных ресурсов.
Под живучей вычислительной системой понимается (виртуальная)
конфигурация из N элементарных машин, в которой:
1) указано минимально допустимое число n работоспособных ВМ,
обеспечивающее производительность системы не менее требуемой;
2) реализована возможность решения сложных задач, представленных
адаптирующимися параллельными программами;
3) отказы любых ВМ (вплоть до числа N-n) и восстановления отказавших
машин приводят только к увеличению или уменьшению времени реализации
параллельной программы;
4) при изменении состояния k = 0, 1, …, N производительность подчиняется
следующему закону:
(k )  An  (k  n)  (n, ),
где An – коэффициент;
107
где – Ω(k) производительность (точнее, один из показателей производительности)
элементарной машины;  ( n, ) – неубывающая функция от n и  (как правило,
 ( n, )  n ).
Следует обратить внимание на то, что в живучей ВС вычислительное ядро
составляют все k  {n, n  1,..., N } исправных ВМ и что число избыточных ВМ в ней
переменное и заключено между 0 и N-n. В живучей системе нет резервирования, нет
простоев исправных машин. Все исправные BМ такой ВС включаются в
вычислительное ядро и участвуют в реализации параллельных процессов, что
приводит к сокращению времени решения задач.
Итак, в живучих ВС отказы вычислительных модулей не приводят к отказу
систем в целом. Более того, в таких ВС при выходе машин из строя сохраняется
возможность продолжения счёта на всех исправных ВМ (при наличии отказавших
вплоть до N-n). Реализация такого виртуального механизма переменной избыточности
машин уменьшает время решения сложной задачи на вычислительной системе.
Показатели живучести ВС должны учитывать то обстоятельство, что при
решении задач используются все исправные ВМ, число которых не есть постоянная
величина. Говоря иначе, при определении показателей живучести следует учесть то,
что параллельные программы сложных задач при их реализации на живучих ВС
способны задействовать суммарную производительность всех работоспособных BМ
системы.
Качество функционирования живучих ВС будем характеризовать функциями
потенциальной живучести ВС N (i, t ) и занятости восстанавливающей системы M(i, t)
вектор-функциями R(t), U(t) и S(t) ВС.
Функции N(i, t) и M(i, t) характеризуют среднюю производительность ВС и
среднюю загруженность восстанавливающей системы, если ВС начала
функционировать с i работоспособными ВМ. Можно дополнить эту системы функций
обобщенными функциями надежности, восстановимости и готовности ВС.
Функцией потенциальной живучести ВС назовём отношение
N (i , t )
,
N
где N(i, t) – среднее число работоспособных ВМ в момент t  0 при условии, что в
момент начала функционирования в системе было i работоспособных ВМ, N – общее
число ВМ системы.
Функцией занятости восстанавливающей системы назовём
M (i , t )
M (i , t ) 
,
m
где M(i,t) – математическое ожидание числа занятых восстанавливающих устройств в
момент времени t  0 при условии, что в момент начала функционирования в системе
было i работоспособных ВМ, m – число устройств в восстанавливающей системе.
Функция потенциальной живучести ВС информирует о том:
1) как быстро система, начавшая функционировать в одном из возможных
состояний, войдёт в стационарный режим работы;
2) какую производительность в среднем может обеспечить система в любой
момент времени или при длительной эксплуатации, говоря иначе, на сколько машин в
среднем можно рассчитывать в момент поступления задачи;
3) сколько машин в среднем может быть использовано при решении задачи
(сколько в среднем ветвей будет иметь место при реализации адаптирующейся
параллельной программы).
Функция занятости восстанавливающей системы даёт следующую
информацию:
N (i , t ) 
108
1) за какое время после начала работы ВС наступит установившийся режим
восстановления отказавших машин;
2) как загружены в среднем восстанавливающие устройства на начальном
участке работы ВС и после длительной её эксплуатации или насколько эффективен
выбранный состав восстанавливающих устройств.
При численном экспериментировании введенные функции потенциальной
живучести ВС и занятости восстанавливающей системы позволяют подобрать
оптимальные параметры единого комплекса «вычислительная система –
восстанавливающая система».
Расчёт функций потенциальной живучести ВС – N(i, t) и занятости
восстанавливающей системы M(i, t) сводится к вычислению математических
ожиданий соответственно числа N(i, t) исправных ВМ и числа M(i, t), занятых ВУ в
момент времени t  0. При этом должно быть выполнено условие, что в начальный
момент t = 0 было i работоспособных машин.
Можно показать, что будет справедливо следующее уравнение:
при чем
d
 (i, t )   (i, t )   (i, t )
dx
'
Рассмотрим
два
случая
в
зависимости
от
производительности
восстанавливающей системы:
1) Восстанавливающая система имеет высокую производительность, то есть
для любого t  0 выполняется условие: N-N(i,t)  m.
Опустим математические выкладки и запишем результат:
 (i, t ) 
N  i  ( N  i )   (    )t

e
, i   N  m,..., N 


,
 (i, t ) 
N  i  ( N  i )   (    )t

e
, i   N  m,..., N 


.
Таким образом можно записать выражения для коэффициентов потенциальной
живучести и занятости восставливающей системы:

N
N
M
 ;
m(   ) .
2) Восстанавливающая система имеет невысокую производительность, то есть
для любого t  0 выполняется условие: N  N (i, t )  m .
Очевидно, что коэффициент занятости восстанавливающей системы
тождественно равен единице: M = M(i,t) =5.
Запишем выражение для среднего числа работоспособных ВМ:
m  i  m    t
 (i, t ) 

e , i  0,1,..., N  m  1


.
Соответственно, коэффициент потенциальной живучести будет равен:
m
N
N .
109
3.4.4. Вопросы к разделу 3.4
1. Какую информацию позволяет получить показатели надежности работы ВС?
2. Какие требования предъявляются к методике рассчета показателей качества
работы ВС?
3. Как оценивается адекватность стохастической модели функционирования ВС
реальному процессу их работы?
4. В чем заключается сущность модели функционирования ВС со структурной
избыточностью?
5. В чем отличие живучести ВС от надежности?
6. В чем разница между понятиями потенциальная живучесть ВС и структурная
живучесть ВС?
7. В чем особенность ВС со свойствами адаптации к составу работоспособных
вычислительных ресурсов?
3.5. Построение живучих ВС, работоспособных в расчетном
диапазоне кратностей отказов
Известно, что повышение надежности системы основано на следующих
принципах:
1)предотвращения
ее
неисправностей
посредством
использования
высоконадежных компонентов со сверхвысокой степенью интеграции,
2) резервирования этих компонентов,
3) поддержания облегченных тепловых и вольт-амперных режимов их работы,
4) экранированием от воздействия разрушающих внешних импульсных,
геомагнитных и радиационных воздействий,
5) совершенствованием методов профилактического обслуживания и сборки
аппаратуры и т.п.
Понятно, что традиционное использование экспоненциальной модели в оценках
надежности составляющих вычислительную систему элементов могло бы быть оправдано
лишь для определения максимального числа , lmax отказов, ожидаемого от эксплуатации
системы в течение всего срока ее службы исключительно в нормативных режимах.
Реальные условия эксплуатации, загруженность системы и качество ее
распределения по элементам системы, существенно меняют загруженность системы и ее
элементов, а следовательно, надежностные показатели и ожидаемое число исправных из
них. Следует учитывать также и то, что наличие минимально необходимого числа
исправных элементарных машин (ЭМ) в системе не гарантирует ее работоспособность
при утрате требуемых для взаимодействия ЭМ коммуникационных качеств.
Отказоустойчивость следует рассматривать как условную вероятность сохранения
системой работоспособности на множестве образов ее неисправностей. Как видно из этого
определения, свойство отказоустойчивости системы не зависит от показателей
надежности составляющих ее элементов. Это свойство определяется её архитектурой,
нацеленной на сохранение способности выполнения ею в реальном времени и с
определенным качеством необходимого минимума функций, достаточного для получения
определенного техническими требованиями результата при возникновении любого отказа
или их группы в пределах заданной кратности.
Отказ от учета функциональной и соответствующей ей структурной составляющих
архитектуры системы сводит анализ отказоустойчивости к частному случаю,
достоверному лишь для анализа полносвязных систем, где число связей равно N-1 , где
N – число ВМ. В реальных же системах сложно строить большие по количеству ВМ
вычислительных систем.
110
Структурная отказоустойчивость системы определена сохранением требуемого для
успешного
функционирования
системы
минимально
необходимого
числа
взаимосвязанных (соответствующих заданным критериям связанности) ВМ при любой
конфигурации отказов с максимально допускаемой кратностью. Показатель структурной
отказоустойчивости вычислительной системы определяет таким образом долю
подмножества работоспособных в множестве возможных конфигураций ВС при
кратности l отказов. При этом минимально допустимое при отказах число ВМ
определяется исходя из их производительности, из набора существенных
функциональных подсистем и их трудоемкости, из граничных значений показателей
реактивности системы в решении этих задач, из плотности вероятности распределения
потока задач и т.д.
Постановка задачи анализа структурной отказоустойчивости вычислительной
системы рассматривает в качестве критических параметров работоспособности
минимально допустимый размер n компоненты связности графа ВС и ее предельный
диаметр d. В связи с постановкой введено понятие d-ограниченной компоненты связности
(d-компоненты связности), выделяющей в графе ВС максимальный связный подграф с
диаметром, не превышающим предельного значения d. Введено также понятие dограниченной связности графа, определяемой как наименьшее число l вершин, удаление
которых приводит к появлению в графе d-компоненты связности с меньшим, чем у
компоненты связности, размером. Синтез отказоустойчивой системы при этом
заключается в определении кратности l отказов, при которой система должна сохранять
работоспособность независимо от конфигурации отказавших ВМ, и в выборе
обеспечивающей это условие структурной конъюнктуры: изначального числа исправных
элементарных машин и их связности. Максимальное значение кратности lmax отказов
определяется при этом коррелированными ожидаемыми условиями эксплуатации
надежностными показателями используемых ВМ, их минимально допустимым числом и
планируемыми значениями вершинной и реберной избыточности исходного графа. Говоря
об условиях эксплуатации, мы включаем сюда как внешние (температурные,
радиационные и т.п.), так и внутренние факторы (загруженность, качества алгоритмов
перераспределения нагрузки и т.п.).
В отличие от надежностного подхода, направленного на создание систем,
высоконадёжных на заданном временном интервале, применяемый подход направлен на
создание систем, работоспособных в расчетном диапазоне кратностей отказов, и основан
на предположении о неизбежности отказов элементов системы в процессе ее
функционирования.
Для характеристики свойств систем могут быть использованы качественные и
экспертные оценки, основанные на опыте разработчиков и применяемые, как правило, при
отсутствии достаточной теоретической базы: адекватной модели системы и методов ее
формального описания. Такие оценки не имеют перспектив при сравнительном анализе
архитектурных вариантов из-за их субъективности. Традиционно используемые оценки
отказоустойчивости и живучести системы методами теории надёжности не являются
явными по своей сути, так как в этом случае оценивается не определённая выше
способность, а вероятность безотказной работы системы в заданном временном интервале
при полной неопределённости корреляционных функций, связывающих характеристики
надёжности с показателями отказоустойчивости и живучести. Недостатками
«надёжностного»
подхода
к
определению
критериев
отказоустойчивого
функционирования системы являются:
- низкая дифференцированность значений надёжностных показателей при
сравнительных оценках вариантов решений, снижающаяся с увеличением структурной
сложности системы и числа составляющих её элементов;
недостаточная
достоверность
среднестатистических
надёжностных
характеристик, не учитывающих возможные отклонения эксплуатационных режимов и
111
параметров внешней среды, в том числе обусловленные человеческим фактором или
каким-либо внешним разрушающим воздействием. Кроме того, использование этих
характеристик в силу их вероятностной природы не исключает возможность отказа
системы в целом;
- надежностные показатели по определению не инвариантны к используемым в
составе системы аппаратным средствам и не дают информации о регенеративных
способностях системы в условиях потока отказов. Это не позволяет абстрагироваться от
надежностных свойств элементов системы и перейти от частных результатов, связанных с
конкретными значениями показателей надежности элементов, к обобщенному анализу
отказоустойчивости и живучести. В формировании свойства отказоустойчивости системы
определяющую роль играют структура и многие другие компоненты ее архитектуры
(методы и принципы организации, стратегии и механизмы функционирования, состав
общесистемного и прикладного программного обеспечения и т.п.), но при надежностном
подходе влияние этих компонентов на отказоустойчивость в принципе не может быть
учтено.
Таким образом, надёжностный подход ориентирован на создание систем, высоко(но не абсолютно) надёжных в заданном временном интервале. Надежность достигается,
прежде всего, путем использования элементов повышенной надёжности, применения
резервирования и мажорирования. Коэффициент аппаратурной избыточности при этом
равен допускаемой в системе кратности отказов.
Рассмотрим подход, направленный на создание систем, сохраняющих
работоспособность в расчетном диапазоне кратностей отказов, и основанный на
оптимизированном распределении различных форм избыточности: от структурной до
алгоритмической. Анализ архитектуры живучих систем и их компонентов проводится в
обобщенной постановке и базируется на моделях, показателях и методах, аксиоматически
предполагающих неизбежность отказов, а не их вероятность. Такой подход позволяет
обеспечить устойчивость системы не только к "естественным" отказам, коррелирующим с
показателями надежности, но и к отказам заданной кратности, обусловленным
неучтенными внутренними факторами или возможными внешними воздействиями.
Необходимая аппаратурная избыточность при таком подходе значительно ниже
допускаемой кратности отказов и для больших систем не превышает нескольких
процентов.
Предложенные показатели живучести и отказоустойчивости не имеют
ограничений на область их приложения и применимы не только для вычислительных
систем, но и при разработке любых систем большой сложности с отказоустойчивой
архитектурой. В частности, такими должны быть необслуживаемые (например, бортовые)
или ограниченно доступные для обслуживания системы, а также системы, отказ которых
может привести к катастрофическим экологическим, экономическим и другим
негативным последствиям.
Важнейшей характеристикой структуры отказоустойчивой системы является ее
связность, как мера защищенности графа системы от распада на несвязанные между собой
части при удалении вершин и (или) ребер. В рамках развиваемого подхода предложим
модель структурно живучей ВС и метод оценки живучести ее структуры, инвариантной к
надежности элементов этой структуры. Предложенная модель и метод позволяют оценить
степень сохранения системой коммуникационных свойств в условиях неизбежной
деградации, вызванной отказами вершин и (или) ребер в графе ВС.
Формально любая система может быть представлена множеством реализуемых ею
существенных (жизненно важных) функций F={F1, F2, …, Fm}.
Система считается живучей, если на любом интервале t (t )  Tmax из заданного
времени ее эксплуатации Tg, ( t  Tg ) множество реализуемых функций Ft включает в себя
множество существенных функций F, F  Ft. При этом время реализации каждой из
112
функций таково, что суммарное время T реализации набора функций не превышает
некоторого заданного максимального значения Tmax.
Невозможность реализации любой из множества F функций, либо выполнение её
вне временных интервалов, определенных выше, означает отказ системы в целом.
Живучесть вычислительной системы определена как свойство, присущее ей в силу
функциональной, структурной, алгоритмической и т.п. организации и заключающееся в
том, что любой отказ (группа отказов), из числа возможных, не выводит систему за
пределы реального времени реализации необходимого минимума функций. Результаты
каждого этапа обработки в случае отказов отдельных компонентов вычислительной
системы должны сохранять свои достоверность, актуальность и достаточность для
выполнения всех последующих этапов работы, включая этапы принятия решения и
выдачи управляющего воздействия. Исследование отказоустойчивости ВС основано на
исследовании графа, вершины которого сопоставлены вычислительным модулям ВС, а
дуги – линиям связи между ними. Отказы в системе моделируются изъятием
соответствующих компонент графа.
Для системы, содержащей N ненадежных компонентов, введем следующие
обозначения: Sl = { Sil } множество возможных состояний при кратности l  N отказов,
Il = {Iil} – множество соответствующих значений показателя качества функционирования,
i  {1, 2, …, |Sl|}.
Определим структурную живучесть, как способность системы сохранять в
требуемых пределах необходимые коммуникационные параметры при заданной кратности
отказов элементов структуры системы в любых их сочетаниях. В этом определении суть
коренного отличие свойств отказоустойчивости и живучести: если показатель
структурной отказоустойчивости предназначен для количественной оценки свойства
системы сохранения ее работоспособности в терминах булевой алгебры (да, нет), то
показатель структурной живучести дает количественную оценку с учетом количественных
критериев сохранением системой этого свойства (в каком диапазоне, насколько хуже).
Для характеристики коммуникационных свойств вычислительных систем введем
понятие соединения. Под соединением пары вершин {m,s} понимаем множество всех
непересекающихся маршрутов между ними. Маршрут Mj(m,s) представляет собой
простую цепь с начальной m и конечной s вершинами и с длиной  . Таким образом,
можем сказать, что система будет оставаться работоспособной при заданном количестве
отказов l, если найдется хотя бы один маршрут соединения пары наиболее удаленных
узлов с длиной не превышающей предельно допустимого значения. Кроме того,
совокупная производительность связанных вычислителей должна быть не менее
требуемой. Цель проектирования такой системы состоит в разработке архитектурных,
программно-технических, методологических и других средств обеспечения адекватности
любой из множества дефектных (с заданной кратностью отказов) конфигураций системы
хотя бы одной конфигурации, допускающей реализацию на ней в реальном времени
множества существенных функций. Оперативность в решении этой задачи определяет
динамику реконфигурирования систем и обусловлена ее сложностью. Суть
реконфигурации подсистемы состоит в актуализации описаний текущей физической
структуры системы, в выявлении адекватных ее текущему состоянию вложений
подсистемы, в выборе из множества адекватных вложений оптимального, и в выполнении
необходимых процедур по реализации последнего.
Приведем в качестве примера три графа (см. рисунки 3.5.1 а), б), и с),
соответственно) отказоустойчивой ВС, состоящей из десяти ВМ.
113
Рисунок 3.5.1. Примеры отказоустойчивых ВС на основе нерегулярных структур
Потребности адекватной и в реальном времени реакции системы на выявленные
отказы инициировали поиск эффективных методов представления графов и решения задач
на них.
Таким образом, задача построения отказоустойчивой ВС может быть решена путем
проецирования ее на плоскость теории графов, которая на настоящее время хорошо
развита. Вообще говоря, проблема построения оптимальной отказоустойчивой ВС на
настоящее время не имеет решения для произвольного числа составных элементов.
3.5.1. Вопросы к разделу 3.5
1. В чем сущность расчетного диапазона кратности отказов?
3. Дайте определение понятия – d-ограниченные компоненты связности.
3. В чем заключается синтез отказоустоячивой ВС при определенной кратности
отказов?
4. Какая основная цель надежностного подхода при создании ВС?
3.6. Реализация модели отказоустойчивых систем
3.6.1. Горячий резерв
Один сервер выполняет приложения, другой находится в горячем резерве.
Дисковые массивы подключены к обоим серверам. Специальные программы,
используя выделенную сеть, следят за состоянием друг друга. При обнаружении сбоя
или отказа по истечении определенного интервала приложения перезапускаются на
том же сервере, если он признан исправным, либо на резервном сервере с
использованием состояния, сохраненного в дисковом массиве. Резервный сервер
может быть менее мощным и исполнять только критичные приложения. Структура
системы показана на рисунке 3.6.1.
114
Рисунок 3.6.1. Отказоустойчивая система по схеме «Горячий резерв»
3.6.2. Репликация
Структура системы с копированием (репликацией) данных показана на
рисунке 3.6.2
Рисунок 3.6.2. Отказоустойчивая система по схеме «Репликация»
В нормальном режиме основной сервер выполняет приложения и копирует
состояние основной базы данных в резервную базу данных либо по завершении
каждой транзакции, либо по истечении заданного интервала времени. В случае отказа,
например, по истечении определенного интервала недоступности после очередной
репликации данных приложения запускаются на резервном сервере.
3.6.3. Кластеры высокой готовности
Эти кластеры применяются там, где стоимость возможного простоя из-за
неполадок значительно превышают стоимость создания отказоустойчивой системы. В
115
таких областях, как биллинговые и банковские системы, электронная коммерция,
управление предприятием и т.д.
Структура кластера с высокой готовностью показана на рисунке 3.6.3.
Рисунок 3.6.3. Отказоустойчивая система по схеме «Кластер высокой готовности»
Рисунок 3.6.4. Отказоутойчивая система смешанного типа
Особенность таких кластеров – они спроектированы таким образом, что
система в целом не имеет точек отказа. Иначе говоря, отсутствуют компоненты,
неполадки которых могут повлиять на работоспособность системы в целом. Для
достижения этой цели не придумано ничего лучше полного дублирования всех
ключевых компонентов кластера (от систем хранения данных до отдельных
коммутаторов и хост – адаптеров). Кроме того, при проектировании учитывается
возможность быстрой замены вышедших из строя элементов без остановки системы.
В определенных случаях используют комбинирование схем, структура таких
систем приведена на рисунке 3.6.4.
116
3.6.4. Вопросы к разделу 3.6
1. Зачем используется горячий резерв в отказоустойчивых системах?
2. С какой целью используется репликация в ВС?
3. Где используются кластеры высокой готовности?
4. Опишите структурную схему отказоустойчивой системы смешанного типа.
117
ГЛАВА 4. БИБЛИОТЕКА ПАРАЛЛЕЛЬНЫХ ПРОГРАММ
4.1 Характеристика параллельных языков программирования
В данной главе рассмотрены две наиболее часто используемые библиотеки
параллельных программ OpenMP и MPI. В случае необходимости достаточно полный
перечень библиотек параллельных программ можно найти в интернете [23]
4.1.1 Характеристика спецификаций OpenMP
Библиотека OpenMP [24] – это набор спецификаций по созданию параллельных
программ в среде с общей памятью. Эта система предоставляет набор прагм, процедур и
переменных среды. Когда эти прагмы используются в программе, они дают указание
компилятору, поддерживающему OpenMP, создать исполнимый модуль, который будет
выполняться параллельно с использованием нескольких потоков. При этом в исходный
код необходимо внести небольшие изменения (отличные от доводки для достижения
максимальной производительности).
Прагмы этой библиотеки позволяют использовать единообразный и переносимый
интерфейс для создания параллельных программ на различных архитектурах и системах.
Модель библиотеки позволяет параллельному программированию подняться на
следующий уровень, создавая для программиста потоки и управляя ими. Все, что
необходимо, это вставить соответствующие прагмы в исходный код программы и затем
скомпилировать
программу
компилятором,
поддерживающим
OpenMP,
с
соответствующим ключевым словом. Компилятор интерпретирует прагмы и создаёт
параллельный код. При использовании компиляторов, не поддерживающих OpenMP, его
прагмы игнорируются без дополнительных сообщений.
Стандарты OpenMP разрабатывались в течение последних 15 лет применительно к
архитектурам с общей памятью для языков Fortran, C, C++. В конце 2005 года компания
Intel предложила систему программирования Cluster OpenMP, реализующий расширение
OpenMP для вычислительных систем с распределенной памятью. Этот система позволяет
объявлять области данных, доступные всем узлам кластера, и осуществлять передачу
данных между узлами кластера неявно с помощью протокола Lazy Release Consistency.
Система позволяет легко и быстро создавать многопоточные приложения на
алгоритмических языках Fortran, C и C++. При этом директивы OpenMP аналогичны
директивам препроцессора для языков C, C++ и являются аналогом комментариев в
алгоритмическом языке Fortran. Это позволяет в любой момент разработки параллельной
реализации программного продукта при необходимости вернуться к последовательному
варианту программы. В настоящее время OpenMP поддерживается большинством
разработчиков параллельных вычислительных систем: компаниями Intel, Hewlett-Packard,
Silicon Graphics, Sun, IBM, Fujitsu, Hitachi, Siemens, Bull и другими. Многие известные
компании в области разработки системного программного обеспечения также уделяют
значительное внимание разработке системного программного обеспечения с OpenMP.
Среди этих компаний отметим Intel, KAI, PGI, PSR, APR, Absoft и некоторые другие.
Значительное
число
компаний
и
научно-исследовательских
организаций,
разрабатывающих прикладное программное обеспечение, в настоящее время использует
OpenMP при разработке своих программных продуктов. Среди этих компаний и
организаций отметим ANSYS, Fluent, Oxford Molecular, NAG, DOE ASCI, Dash, Livermore
Software. Среди российских компаний следует отметить ТЕСИС, Центральную
геофизическую экспедицию и российские научно-исследовательские организации. К ним
118
относятся – Институт математического моделирования РАН, Институт прикладной
математики имени Келдыша РАН, Вычислительный центр РАН, Научноисследовательский вычислительный центр МГУ, Институт химической физики РАН и
другие.
Разработкой стандарта занимается организация OpenMP ARB (ARchitecture Board),
в которую вошли представители крупнейших компаний – разработчиков SMP-архитектур
и программного обеспечения. Спецификации для языков Fortran, C и C++ появились
соответственно в октябре 1997 года и октябре 1998 года.
Согласно терминологии POSIX threads, любой UNIX-процесс содержит несколько
нитей управления (потоков, легковесных процессов), имеющих общее адресное
пространство, но разные потоки команд и раздельные стэки. Самый простой процесс
состоит из одной нити. POSIX-интерфейс для организации нитей (Pthreads)
поддерживается широко (практически на всех UNIX-системах), однако по многим
причинам не подходит для практического параллельного программирования: нет
поддержки языком Fortran, слишком низкий уровень, нет поддержки параллелизма по
данным, механизм нитей изначально разрабатывался не для целей организации
параллелизма.
OpenMP можно рассматривать как высокоуровневую надстройку над Pthreads
(динамически порождаемые нити, общие и разделяемые данные, механизм «замков» для
синхронизации).
Многие поставщики SMP-архитектур (Sun, HP, SGI) в своих компиляторах
поддерживают специальные директивы для распараллеливания циклов. Однако эти
наборы директив, как правило: 1) весьма ограничены; 2) несовместимы между собой, в
результате чего разработчикам приходится распараллеливать приложение отдельно для
каждой платформы. OpenMP является во многом обобщением и расширением упомянутых
наборов директив.
При использовании OpenMP разработчик получает некоторые преимущества:
1. За счет идеи независимого распараллеливания отдельных участков программ эта
библиотека идеально подходит для разработчиков, желающих быстро распараллелить
свои вычислительные программы с большими параллельными циклами. Разработчик не
создает новую параллельную программу, а просто последовательно добавляет в текст
последовательной программы соответствующие директивы.
2. Разработчику предоставляются большие возможности контроля над поведением
параллельного приложения.
3. Предполагается, что OpenMP-программа на однопроцессорной платформе может
быть использована в качестве последовательной программы, т.е. нет необходимости
поддерживать последовательную и параллельную версии. Директивы распараллеливания
просто игнорируются последовательным компилятором, а для вызова процедур
библиотеки могут быть подставлены заглушки (stubs), текст которых приведен в
спецификациях.
4. Одним из достоинств рассматриваемой системы её разработчики считают
наличие директив синхронизации и распределения работы, которые дают возможность не
входить непосредственно в лексический контекст параллельной области.
4.1.2. Принципиальная схема программирования в OpenMP
Любая программа, последовательная или параллельная, состоит из набора областей
двух типов: последовательных областей и областей распараллеливания. При выполнении
последовательных областей порождается только один главный поток (процесс). В этом же
потоке инициируется выполнение программы, а также происходит ее завершение. В
последовательной программе в областях распараллеливания порождается также только
один, главный поток, и этот поток является единственным на протяжении выполнения
119
всей программы. В параллельной программе в областях распараллеливания порождается
целый ряд параллельных потоков. Порожденные параллельные потоки могут выполняться
как на разных процессорах, так и на одном процессоре вычислительной системы. В
последнем случае параллельные процессы (потоки) конкурируют между собой за доступ к
процессору. Управление конкуренцией осуществляется планировщиком операционной
системы с помощью специальных алгоритмов. В операционной системе Linux
планировщик задач осуществляет обработку процессов с помощью стандартного
карусельного (round-robin) алгоритма. При этом только администраторы системы имеют
возможность изменить или заменить этот алгоритм системными средствами. Таким
образом, в параллельных программах в областях распараллеливания выполняется ряд
параллельных потоков. Принципиальная схема параллельной программы изображена на
рисунке 4.1.1.
Рисунок 4.1.1. Принципиальная схема параллельной программы
При выполнении параллельной программы работа начинается с инициализации и
выполнения главного потока (процесса), который по мере необходимости создает и
выполняет параллельные потоки, передавая им необходимые данные. Параллельные
потоки из одной параллельной области программы могут выполняться как независимо
друг от друга, так и с пересылкой и получением сообщений от других параллельных
потоков. Последнее обстоятельство усложняет разработку программы, поскольку в этом
случае программисту приходится заниматься планированием, организацией и
синхронизацией посылки сообщений между параллельными потоками. Таким образом,
при разработке параллельной программы желательно выделять такие области
распараллеливания, в которых можно организовать выполнение независимых
параллельных потоков. Для обмена данными между параллельными процессами
(потоками) в OpenMP используются общие переменные. При обращении к общим
переменным в различных параллельных потоках возможно возникновение конфликтных
ситуаций при доступе к данным. Для предотвращения конфликтов можно воспользоваться
процедурой синхронизации (synchronization). При этом надо иметь в виду, что процедура
синхронизации – очень дорогая операция по временным затратам и желательно по
возможности избегать ее или применять как можно реже. Для этого необходимо очень
тщательно продумывать структуру данных программы.
Выполнение параллельных потоков в параллельной области программы начинается
с их инициализации. Она заключается в создании дескрипторов порождаемых потоков и
копировании всех данных из области данных главного потока в области данных
создаваемых параллельных потоков. Эта операция чрезвычайно трудоемка – она
эквивалентна примерно трудоемкости 1000 операций. Эта оценка чрезвычайно важна при
разработке параллельных программ c помощью OpenMP, поскольку ее игнорирование
ведет к созданию неэффективных параллельных программ, которые оказываются
зачастую медленнее их последовательных аналогов. В самом деле: для того чтобы
получить выигрыш в быстродействии параллельной программы, необходимо, чтобы
120
трудоемкость параллельных процессов в областях распараллеливания программы
существенно превосходила бы трудоемкость порождения параллельных потоков. В
противном случае никакого выигрыша по быстродействию получить не удастся, а
зачастую можно оказаться даже и в проигрыше.
После завершения выполнения параллельных потоков управление программой
вновь передается главному потоку. При этом возникает проблема корректной передачи
данных от параллельных потоков главному. Здесь важную роль играет синхронизация
завершения работы параллельных потоков, поскольку в силу целого ряда обстоятельств
время выполнения даже одинаковых по трудоемкости параллельных потоков
непредсказуемо (оно определяется как историей конкуренции параллельных процессов,
так и текущим состоянием вычислительной системы). При выполнении операции
синхронизации параллельные потоки, уже завершившие свое выполнение, простаивают и
ожидают завершения работы самого последнего потока. Естественно, при этом неизбежна
потеря эффективности работы параллельной программы. Кроме того, операция
синхронизации имеет трудоемкость, сравнимую с трудоемкостью инициализации
параллельных потоков, т. е. эквивалентна примерно трудоемкости выполнения 1000
операций.
На основании изложенного выше можно сделать следующий важный вывод: при
выделении параллельных областей программы и разработке параллельных процессов
необходимо, чтобы трудоемкость параллельных процессов была не менее 2000 операций
деления. В противном случае параллельный вариант программы будет проигрывать в
быстродействии последовательной программе. Для эффективной работающей
параллельной программы этот предел должен быть существенно превышен.
4.1.3. Описание основных конструкций OPEN MP
Спецификация OpenMP определяет набор прагм. Прагма – это директива
компилятора, указывающая, как обрабатывать код, следующий за прагмой.
#pragma omp parallel, одна из наиболее важных прагм, определяющая
область параллельности.
В рассматриваемой библиотеке используется модель параллельного выполнения
«ветвление-слияние». Программа OpenMP начинается как единственный поток
выполнения, называемый начальным потоком. Когда поток встречает параллельную
конструкцию, он создает новую группу потоков, состоящую из себя и неотрицательного
числа дополнительных потоков, и становится главным в новой группе. Все члены новой
группы (включая главный) выполняют код внутри параллельной конструкции. В конце
параллельной конструкции имеется неявный барьер. После параллельной конструкции
выполнение пользовательского кода продолжает только главный поток. Число потоков в
группе, выполняющихся в области параллельности, можно контролировать несколькими
способами. Один из них – использование переменной среды OMP_NUM_THREADS.
Другой способ – вызов процедуры omp_set_num_threads(). Еще один способ –
использование выражения num_threads в сочетании с прагмой parallel.
В OpenMP поддерживаются две основных конструкции разделения работы для
указания того, что работу в области параллельности следует разделить между потоками
группы. Эти конструкции разделения работы – циклы и разделы.
Прагма #pragma omp for используется для циклов;
Прагма #pragma omp sections используется для разделов – блоков кода,
которые могут быть выполнены параллельно.
121
Прагма #pragma omp barrier дает всем потокам указание ожидать друг
друга перед тем, как они продолжат выполнение за барьером. Как было
отмечено выше, в конце области параллельности имеется неявный барьер.
Прагма #pragma omp master дает компилятору указание о том, что
следующий блок кода должен выполняться только главным потоком.
Прагма #pragma omp single показывает, что следующий блок кода
должен выполняться только одним потоком группы; этот поток не
обязательно должен быть главным.
Прагма #pragma omp critical может использоваться для защиты блока
кода, который должен выполняться одновременно только одним
потоком.
Конечно, все эти прагмы имеют смысл только в контексте прагмы parallel (области
параллельности).
OpenMP предоставляет ряд процедур, которые можно использовать для получения
сведений о потоках в программе. В их число входят omp_get_num_threads(),
omp_set_num_threads(), omp_get_max_threads(), omp_in_parallel() и другие. Кроме того,
предоставляется ряд процедур блокировки, которые можно использовать для
синхронизации потоков.
Все директивы OpenMP располагаются в комментариях и начинаются с одной из
следующих комбинаций: !$OMP, C$OMP или *$OMP (напомним, что строка,
начинающаяся с одного из символов «!», «C» или «*» по правилам языка Фортран
считается комментарием). В дальнейшем изложении при описании конкретных директив
для сокращения записи мы иногда будем опускать эти префиксы, хотя в реальных
программах они, конечно же, всегда должны присутствовать. Все переменные окружения
и функции, относящиеся к OpenMP, начинаются с префикса OMP_ . Для определения
параллельных областей программы используется пара директив
!$OMP PARALLEL
< параллельный код программы >
!$OMP END PARALLEL
Для выполнения кода, расположенного между данными директивами,
дополнительно порождается OMP_NUM_THREADS-1 нитей, где OMP_NUM_THREADS –
это переменная окружения, значение которой пользователь, вообще говоря, может
изменять. Процесс, выполнивший данную директиву (нить-мастер), всегда получает
номер 0. Все нити исполняют код, заключенный между данными директивами. После END
PARALLEL автоматически происходит неявная синхронизация всех нитей, и как только
все нити доходят до этой точки, нить-мастер продолжает выполнение последующей части
программы, а остальные нити уничтожаются. Параллельные секции могут быть
вложенными одна в другую. По умолчанию вложенная параллельная секция исполняется
одной нитью.
Необходимую стратегию обработки вложенных секций определяет
переменная OMP_NESTED, значение которой можно изменить с помощью
функции OMP_SET_NESTED.
Если значение переменной OMP_DYNAMIC установлено в 1, то с помощью
функции OMP_SET_NUM_THREADS пользователь может изменить
122
значение переменной OMP_NUM_THREADS, а значит
порождаемых при входе в параллельную секцию нитей.
и
Значение переменной
OMP_SET_DYNAMIC.
функцией
OMP_DYNAMIC
контролируется
число
Необходимость порождения нитей и параллельного исполнения кода
параллельной секции пользователь может определять динамически с
помощью дополнительной опции IF в директиве !$OMP PARALLEL IF(
<условие> ) Если <условие> не выполнено, то директива игнорируется и
продолжается обработка программы в прежнем режиме.
Мы уже говорили о том, что все порожденные нити исполняют один и тот же код.
Теперь нужно обсудить вопрос, как разумным образом распределить между ними работу.
OpenMP предлагает несколько вариантов. Можно программировать на самом низком
уровне, распределяя работу с помощью функций OMP_GET_THREAD_NUM и
OMP_GET_NUM_THREADS, возвращающих номер нити и общее количество
порожденных нитей соответственно. Например, если написать фрагмент вида:
IF( OMP_GET_THREAD_NUM() .EQ. 3 ) THEN
< код для нити с номером 3 >
ELSE
< код для всех остальных нитей >
ENDIF ,
то часть программы между директивами IF - ELSE будет выполнена только нитью с
номером 3, а часть между ELSE – ENDIF – всеми остальными. Как и прежде, этот код
будет выполнен всеми нитями, однако функция OMP_GET_THREAD_NUM() возвратит
значение 3 только для нити с номером 3, поэтому и выполнение данного участка кода для
третьей нити и всех остальных будет идти по-разному. Если в параллельной секции
встретился оператор цикла, то, согласно общему правилу, он будет выполнен всеми
нитями, т.е. каждая нить выполнит все итерации данного цикла. Для распределения
итераций цикла между различными нитями можно использовать директиву
!$OMP DO [опция [[,] опция]:]
!$OMP END DO ,
которая относится к идущему следом за данной директивой оператору DO.
Опция SCHEDULE определяет конкретный способ распределения итераций
данного цикла по нитям:
STATIC [,m] – блочно-циклическое распределение итераций: первый блок из
m итераций выполняет первая нить, второй блок - вторая и т.д. до
последней нити, затем распределение снова начинается с первой нити; по
умолчанию значение m равно 1;
DYNAMIC [,m] – динамическое распределение итераций с фиксированным
размером блока: сначала все нити получают порции из m итераций, а
затем каждая нить, заканчивающая свою работу, получает следующую
порцию опять-таки из m итераций;
GUIDED [,m] – динамическое распределение итераций блоками
уменьшающегося размера; аналогично распределению DYNAMIC, но
123
размер выделяемых блоков все время уменьшается, что в ряде случаев
позволяет аккуратнее сбалансировать загрузку нитей;
RUNTIME – способ распределения итераций цикла выбирается во время
работы программы в зависимости от значения переменной
OMP_SCHEDULE.
Выбранный способ распределения итераций указывается в скобках после опции
SCHEDULE, например:
!$OMP DO SCHEDULE (DYNAMIC, 10)
В данном примере будет использоваться динамическое распределение итераций
блоками по 10 итераций. В конце параллельного цикла происходит неявная барьерная
синхронизация параллельно работающих нитей: их дальнейшее выполнение происходит
только тогда, когда все они достигнут данной точки. Если в подобной задержке нет
необходимости, то директива END DO NOWAIT позволяет нитям уже дошедшим до конца
цикла продолжить выполнение без синхронизации с остальными. Если директива END DO
в явном виде и не указана, то в конце параллельного цикла синхронизация все равно будет
выполнена. Рассмотрим следующий пример, расположенный в параллельной секции
программы:
!$OMP DO SCHEDULE (STATIC, 2)
DO i = 1, n
DO j = 1, m
A( i, j) = ( B( i, j-1) + B( i-1, j) ) / 2.0
END DO
END DO
!$OMP END DO
В данном примере внешний цикл объявлен параллельным, причем будет
использовано блочно-циклическое распределение итераций по две итерации в блоке.
Относительно внутреннего цикла никаких указаний нет, поэтому он будет выполняться
последовательно каждой нитью.
Параллелизм на уровне независимых фрагментов оформляется в OpenMP с
помощью директивы SECTIONS - END SECTIONS:
!$OMP SECTIONS
< фрагмент 1>
!$OMP SECTIONS
< фрагмент 2>
!$OMP SECTIONS
< фрагмент 3>
!$OMP END SECTIONS
В данном примере программист описал, что все три фрагмента информационно
независимы, и их можно исполнять в любом порядке, в частности, параллельно друг
другу. Каждый из таких фрагментов будет выполнен какой-либо одной нитью. Если в
параллельной секции какой-то участок кода должен быть выполнен лишь один раз (такая
ситуация иногда возникает, например, при работе с общими переменными), то его нужно
поставить между директивами SINGLE - END SINGLE. Такой участок кода будет
выполнен нитью, первой дошедшей до данной точки программы.
124
Одно из базовых понятий OpenMP – классы переменных. Все переменные,
используемые в параллельной секции, могут быть либо общими, либо локальными.
Общие переменные описываются директивой SHARED, а локальные директивой
PRIVATE. Каждая общая переменная существует лишь в одном экземпляре и доступна
для каждой нити под одним и тем же именем. Для каждой локальной переменной в
каждой нити существует отдельный экземпляр данной переменной, доступный только
этой нити. Предположим, что следующий фрагмент расположен в параллельной секции:
I = OMP_GET_THREAD_NUM()
PRINT *, I
Если переменная I в данной параллельной секции была описана как локальная, то
на выходе будет получен весь набор чисел от 0 до OMP_NUM_THREADS-1, идущих,
вообще говоря, в произвольном порядке, но каждое число встретиться только один раз.
Если же переменная I была объявлена общей, то единственное, что можно сказать с
уверенностью – мы получим последовательность из OMP_NUM_THREADS чисел,
лежащих в диапазоне от 0 до OMP_NUM_THREADS-1 каждое. Сколько и каких именно
чисел будет в последовательности заранее сказать нельзя. В предельном случае, это может
быть даже набор из OMP_NUM_THREADS одинаковых чисел I0. Предположим, что все
процессы, кроме процесса I0, выполнили первый оператор, но затем их выполнение по
какой-то причине было прервано. В это время процесс с номером I0 присвоил это
значение переменной I, а поскольку данная переменная является общей, то одно и то же
значение затем и будет выведено каждой нитью.
Целый набор директив в OpenMP предназначен для синхронизации работы нитей.
Самый распространенный способ синхронизации – барьер.
!$OMP BARRIER .Все нити, дойдя до этой директивы, останавливаются
и ждут пока все нити не дойдут до этой точки программы, после чего все
нити продолжают работать дальше.
Две директивы MASTER - END MASTER выделяет участок кода,
который будет выполнен только нитью-мастером. Остальные нити
пропускают данный участок и продолжают работу с выполнения
оператора, расположенного следом за директивой END MASTER.
С помощью директив
!$OMP CRITICAL [ (<имя_критической_секции>) ]
...
!$OMP END CRITICAL [ (< имя_ критической_секции >) ],
оформляется критическая секция программы. В каждый момент времени
в критической секции может находиться не более одной нити. Если
критическая секция уже выполняется какой-либо нитью P0, то все другие
нити, выполнившие директиву для секции с данным именем, будут
заблокированы, пока нить P0 не закончит выполнение данной критической
секции. Как только P0 выполнит директиву END CRITICAL, одна из
заблокированных на входе нитей войдет в секцию. Если на входе в
критическую секцию стояло несколько нитей, то случайным образом
выбирается одна из них, а остальные заблокированные нити продолжают
ожидание. Все неименованные критические секции условно ассоциируются
с одним и тем же именем.
Частым случаем использования критических секций на практике является
обновление общих переменных. Например, если переменная SUM является общей и
125
оператор вида SUM=SUM+Expr находится в параллельной секции программы, то при
одновременном выполнении данного оператора несколькими нитями можно получить
некорректный результат. Чтобы избежать такой ситуации можно воспользоваться
механизмом критических секций или специально предусмотренной для таких случаев
директивой ATOMIC:
!$OMP ATOMIC
SUM=SUM+Expr .
Данная директива относится к идущему непосредственно за ней
оператору, гарантируя корректную работу с общей переменной, стоящей
в левой части оператора присваивания.
Поскольку в современных параллельных вычислительных системах может
использоваться сложная структура и иерархия памяти, пользователь должен иметь
гарантии того, что в необходимые ему моменты времени каждая нить будет видеть
единый согласованный образ памяти. Именно для этих целей и предназначена директива
!$OMP FLUSH [ список_переменных ]. Выполнение данной директивы
предполагает, что значения всех переменных, временно хранящиеся в
регистрах, будут занесены в основную память, все изменения переменных,
сделанные нитями во время их работы, станут видимы остальным
нитям, если какая-то информация хранится в буферах вывода, то буферы
будут сброшены и т.п.
Поскольку выполнение данной директивы в полном объеме может повлечь
значительных накладных расходов, а в данный момент нужна гарантия согласованного
представления не всех, а лишь отдельных переменных, то эти переменные можно явно
перечислить в директиве списком.
4.1.4. Способы построения параллельных программ
На примере простой программы умножения матриц можно увидеть, как
использовать OpenMP для создания параллельной программы. Рассмотрим следующий
небольшой фрагмент программы умножения двух матриц, используя достаточно простой
алгоритм.
for (ii = 0; ii < dim; ii++) {
for (jj = 0; jj < dim; jj++) {
for (kk = 0; kk < dim; kk++) {
array[ii][jj] += array1[ii][kk] * array2[kk][jj];
}
}
}
Обратите внимание, что на каждом уровне вложенности циклов тела циклов могут
выполняться независимо друг от друга. Так что создать фрагмент параллельной
программы достаточно просто: необходимо вставить прагму #pragma omp parallel for
перед самым внешним циклом (циклом по переменной ii). Лучше всего вставить прагму
перед самым внешним циклом, так как это даст наибольший выигрыш в
производительности. В преобразованном цикле переменные array, array1, array2 и dim
являются общими для потоков, а переменные ii, jj и kk являются частными для каждого
потока. Приведенный выше фрагмент преобразуется к виду:
126
#pragma omp parallel for shared(array, array1, array2, dim) private(ii, jj, kk)
for (ii = 0; ii < dim; ii++) {
for (jj = 0; jj < dim; jj++) {
for (kk = 0; kk < dim; kk++) {
array[ii][jj] = array1[ii][kk] * array2[kk][jj];
}
}
}
В качестве другого примера рассмотрим следующий фрагмент кода,
предназначенный для вычисления суммы значений f(x) для целых аргументов из
интервала 0 <= x < n.
for (ii = 0; ii < n; ii++) {
sum = sum + some_complex_long_fuction(a[ii]);
}
Для построения параллельной программы приведенного выше фрагмента в
качестве первого шага можно сделать следующее:
#pragma omp parallel for shared(sum, a, n) private(ii, value)
for (ii = 0; ii < n; ii++) {
value = some_complex_long_fuction(a[ii]);
#pragma omp critical
sum = sum + value;
}
или, что лучше, можно использовать оператор приведения, в результате чего
получится
#pragma omp parallel for shared(a, n) private(ii) reduction(+: sum)
for (ii = 0; ii < n; ii++) {
sum = sum + some_complex_long_fuction(a[ii]);
}
Анализируя выше приведенные примеры, можно сделать вывод, что создавать
параллельные программы можно несколькими способами. Во-первых, следует
определить, поддаётся ли алгоритм распараллеливанию. Если создается новый проект, то
можно выбрать алгоритм, который может быть распараллелен. Предварительно очень
важно убедиться, что программа выполняется правильно в последовательном режиме.
Необходимо также определить временные характеристики при последовательном
выполнении, по которым можно будет принять решение о целесообразности
распараллеливания.
Скомпилируйте последовательную версию в нескольких режимах оптимизации.
Вообще говоря, компилятор может выполнить гораздо более серьезную оптимизацию, чем
сам программист.
По мере готовности программы для распараллеливания, можно применить ряд
функций и средств Sun Studio, которые помогут достигнуть цели. Они кратко описаны
ниже.
Можно попробовать применить ключ автоматического распараллеливания
компилятора (-xautopar). Доверив распараллеливание компилятору, программист может
получить требуемую программу без каких-либо усилий со своей стороны. Кроме того,
127
автоматический распараллеливатель может помочь определить фрагменты программы,
которые можно распараллеливать с помощью прагм OpenMP, и в особенности, которые
могут помешать распараллеливанию (например, зависимости между повторениями тела
цикла). Комментарии компилятора можно просмотреть, скомпилировав программу с
ключом – g, и использовав служебную программу er_src(1) из состава Sun Studio,
например, следующим образом:
% cc -g -xautopar -c source.c
% er_src source.o
Одним из наиболее распространенных типов ошибок в программировании с
использованием OpenMP являются ошибки в определении области действия переменных,
когда область действия переменной указывается неверно, например, переменная
определяется как общая (частная), в то время как ее нужно определить как частную
(общую). Функция автоопределения области действия переменных в компиляторах Sun
Studio освобождает программиста от задачи определения областей действия переменных.
Поддерживаются два расширения OpenMP: оператор __auto и оператор default(__auto).
Отладчик Sun Studio, dbx, поддерживает работу с потоками и может использоваться для
отладки программы, использующей OpenMP. Для отладки программы, использующей
OpenMP, следует, во-первых, скомпилировать программу без какой-либо оптимизации,
использовав ключи компилятора –xopenmp = noopt -g, затем запустить dbx для отладки
полученного исполнимого модуля. С помощью dbx можно устанавливать точки останова
внутри области параллельности и выполнять программу в области параллельности в
пошаговом режиме, проверять переменные, являющиеся частными для потока, и так
далее. Система Sun Studio позволяет производить определение узких мест в программе.
Анализатор производительности Sun Studio можно использовать для разных целей.
Это средство можно использовать для определения критических областей в программе,
занимающих большую часть времени. Кроме того, это средство предоставляет
возможности измерения времени работы и ожидания для функций, что может помочь в
определении узких мест в программе, использующей OpenMP.
4.1.5 Спецификация OpenMP для языков C и C++
Спецификация OpenMP для C и C++, выпущенная на год позже фортранной,
содержит в основном аналогичную функциональность.
Необходимо лишь отметить следующие моменты:
1) Вместо специальных комментариев используются директивы компилятора
«#pragma omp».
2) Компилятор с поддержкой OpenMP определяет макрос «_OPENMP», который
может использоваться для условной компиляции отдельных блоков, характерных для
параллельной версии программы.
3) Распараллеливание применяется к for-циклам, для этого используется директива
«#pragma omp for». В параллельных циклах запрещается использовать оператор break.
4) Статические (static) переменные, определенные в параллельной области
программы, являются общими (shared).
5) Память, выделенная с помощью malloc(), является общей (однако указатель на
нее может быть как общим, так и приватным).
6) Типы и функции OpenMP определены во включаемом файле <omp.h>.
7) Кроме обычных, возможны также «вложенные» (nested) замки – вместо
логических переменных используются целые числа. Нить, уже захватившая замок, при
повторном захвате может увеличить это число.
128
Пример распараллеливания for-цикла в C:
#pragma omp parallel for private(i)
#pragma omp shared(x, y, n) reduction(+: a, b)
for (i=0; i<n; i++)
{
a = a + x[i];
b = b + y[i];
}
Знать, когда использовать технологию OpenMP, не менее важно, чем уметь с ней
работать. Целевая платформа является многопроцессорной или многоядерной. Если
приложение полностью использует ресурсы одного ядра или процессора, то, сделав его
многопоточным при помощи OpenMP, вы почти наверняка повысите его быстродействие.
Приложение должно быть кроссплатформенным. А так как оно реализовано
на основе директив pragma, приложение можно скомпилировать даже при помощи
компилятора, не поддерживающего стандарт OpenMP.
Выполнение циклов нужно распараллелить. Весь свой потенциал OpenMP
демонстрирует при организации параллельного выполнения циклов. Если в приложении
есть длительные циклы без зависимостей, OpenMP – идеальное решение.
Перед выпуском приложения нужно повысить его быстродействие. Так как
технология OpenMP не требует переработки архитектуры приложения, она прекрасно
подходит для внесения в программу небольших изменений, позволяющих повысить его
быстродействие.
Эта
технология
ориентирована
в первую
очередь
на разработчиков
высокопроизводительных вычислительных систем и наиболее эффективна, если
программа включает много циклов и работает с разделяемыми массивами данных.
Большинство параллельных циклов будут выполняться быстрее последовательных
даже при значительно меньшем числе итераций. Это зависит от объема работы,
выполняемой на каждой итерации. При этом важно оценивать производительность ПО,
так как само по себе применение OpenMP не гарантирует, что быстродействие вашего
кода повысится.
OpenMP-директивы pragma просты в использовании, но не позволяют получать
детальные сведения об ошибках. Еще одна ситуация, в которой следует сохранять
бдительность, имеет место при использовании потоков Windows вместе с потоками
OpenMP. Потоки OpenMP создаются на основе потоков Windows, поэтому они прекрасно
работают в одном процессе. Увы, OpenMP ничего не знает о потоках Windows, созданных
другими модулями. Из этого вытекают две проблемы: во-первых, исполняющая среда
OpenMP не ведет учет других потоков Windows, а во-вторых, методы синхронизации
OpenMP не синхронизируют потоки Windows, потому что они не входят в группы
потоков.
4.1.6. Вопросы к разделу 4.1
1.
Какая
модель
параллельных
вычислений
используется
в
библиотеке OpenMP?
2. Какие директивы используются для создания и ликвидации нитей?
3. Какие существуют способы построения параллельных программ ?
4. Охарактеризуйте нисходящие и восходящие к корню, покрывающие
ориентированные деревья.
5. Каким способом определяются области действия переменных в
компиляторах Open MP?
129
6. В чём специфика использования потоков OpenMP на основе потоков
Windows?
7. Какие этапы надо выполнить перед запуском программы в Open MP?
4.2. Основы построения библиотеки MPI
4.2.1. Основные понятия
Одной из распространённых технологий программирования для создания
параллельных программ в настоящее время является библиотека МРI (Message Passing
Interfase – интерфейс передачи данных) [29]. Для этой библиотеки выработано
несколько стандартов. Наиболее часто используемым стандартом в настоящее время
является стандарт МРI 1.1 образца 1997 – 1998гг. Последняя версия стандарта - 2.0. В этой
версии к MPI добавлены такие важные элементы функциональности, как динамическое
управление процессами, односторонние коммуникации (Put/Get), параллельный
ввод/вывод. Однако ни в одной реализации на настоящее время интерфейс MPI 2.0
полностью не поддерживается. Основным способом взаимодействия параллельных
процессов в этой библиотеке является передача сообщений. Стандарт МPI фиксирует
интерфейс, который должен соблюдаться как рассматриваемой библиотекой на
каждой вычислительной платформе, так и пользователем при создании своих программ.
Библиотека МРI поддерживает работу с языками Фортран и Си. В данном разделе
будут изложены основные положения MPI стандарта. Более подробные сведения
приведены в интернете [28].
Далее в тексте примеры и описания всех процедур будут даны с использованием
языка Си иллюстрирующие основные возможности этой библиотеки. Полная версия MPI
стандарта содержит описание более 125 процедур и функций. Интерфейс МPI
поддерживает создание параллельных программ в стиле МIМD, что подразумевает
объединение процессов с различными программными модулями. При использовании
стандарта MPI компиляция программы требует подключения модулей библиотеки MPI.
Это можно сделать в командной строке или воспользоваться предусмотренными в
большинстве систем командами или скриптами mрicc (для программ на языке Си),
mрiСС (для программ на языке Си++), и mрif77/mpif90 (для программ на языках Фортран
77/90). Опция компилятора <—о паmе> позволяет задать имя nаше для получаемого
выполнимого файла, по умолчанию выполнимый файл называется а.оut, например:
mрiCC -о рrоgrаm рrоgrаm.c
После получения выполнимого файла необходимо запустить его на требуемом
количестве процессоров. Для этого обычно предоставляется команда запуска МPIприложений mрiruп, например:
mрirun -nр N <программа с аргументами>,
где N – число процессов, которое должно быть не более разрешенного в данной
системе числа процессов для одной задачи. После запуска одна и та же программа будет
выполняться всеми запущенными процессами, результат выполнения в зависимости от
системы будет выдаваться на терминал или записываться в файл с предопределенным
именем.
Все дополнительные объекты: имена процедур, константы, предопределенные
типы данных и т.п., используемые в МРI, описаны в библиотеке mpi.h и имеют
префикс MPI_. В языке Си, кроме того, является существенным регистр символов в
названиях функций. Обычно в названиях функций МPI первая буква после префикса
130
MPI_ пишется в верхнем регистре, последующие буквы — в нижнем регистре, а названия
констант МPI записываются целиком в верхнем регистре.
МPI-программа – это множество параллельных взаимодействующих процессов.
Все процессы порождаются один раз, образуя параллельную часть программы. В ходе
выполнения МPI-программы не допускается порождение дополнительных процессов или
уничтожение уже существующих. Каждый процесс работает в своем адресном
пространстве , никаких общих переменных или данных в МPI нет. Основным способом
взаимодействия между процессами является явная посылка сообщений.
Для локализации взаимодействия параллельных процессов программы можно
создавать группы процессов, предоставляя им отдельную среду для общения –
коммуникатор. Состав образуемых групп произволен. Группы могут полностью
совпадать, входить одна в другую, не пересекаться или пересекаться частично. Процессы
могут взаимодействовать только внутри некоторого коммуникатора, сообщения,
отправленные в разных коммуникаторах , не пересекаются и не мешают друг другу.
Коммуникаторы имеют в языке Си — предопределенный тип MPI_Соmm. При старте
программы всегда считается, что все порожденные процессы работают в рамках
всеобъемлющего коммуникатора, имеющего предопределенное имя MPI_СOMM_WORLD.
Этот коммуникатор существует всегда и служит для взаимодействия всех запущенных
процессов МPI-программы. Кроме него при старте программы имеется коммуникатор
MPI_СOMM_SELF, содержащий только один текущий процесс, а также коммуникатор
MPI_СOMM_NULL, не содержащий ни одного процесса. Каждый процесс MPIпрограммы имеет в каждой группе, в которую он входит, уникальный атрибут - номер
процесса, который является целым неотрицательным числом. С помощью этого атрибута
происходит значительная часть взаимодействия процессов между собой. Ясно, что в
одном и том же коммуникаторе все процессы имеют различные номера. Но поскольку
процесс может одновременно входить в разные коммуникаторы, то его номер в одном
коммуникаторе может отличаться от его номера в другом. Отсюда становятся понятными
два основных атрибута процесса коммуникатор и номер в коммуникаторе. Если группа
содержит n процессов, то номер любого процесса в данной группе лежит в пределах от 0
до n — 1.
Основным способом общения процессов между собой является явная посылка
сообщений. Сообщение – это набор данных некоторого типа. Каждое сообщение имеет
несколько атрибутов, в частности, номер процесса-отправителя, номер процессаполучателя, идентификатор сообщения и другие. По идентификатору процесс,
принимающий сообщение, например, может различить два сообщения, пришедшие к
нему от одного и того же процесса. Сам идентификатор сообщения является целым
неотрицательным числом, лежащим в диапазоне от 0 до MPI_TAG_UP, причем
гарантируется, что MPI_TAG_UP не меньше 32767. Для работы с атрибутами сообщений
введен массив (в языке Си — структура), элементы которого дают доступ к их
значениям.
В последнем аргументе (в языке Си — в возвращаемом значении функции)
большинство процедур МРI возвращают информацию об успешности завершения. В
случае успешного выполнения возвращается значение MPI_SUССESS, иначе — код
ошибки. Вид ошибки, которая произошла при выполнении процедуры, можно будет
определить из ее описания. Предопределенные значения, соответствующие различным
ошибочным ситуациям, перечислены в файле mрif.h.
Рассмотрим часто используемые функции MPI:
INTEGER IERR;
MPI_INIT(IERR);
Инициализация параллельной части программы. Все другие процедуры МРI могут
быть вызваны только после вызова MPI_INIT. Инициализация параллельной части для
131
каждого приложения должна выполняться только один раз. В языке Си функции
MPI_Iпit передаются указатели на аргументы командной строки программы аrgc и аrgv,
из которых системой могут извлекаться и передаваться в параллельные процессы
некоторые параметры запуска программы:
MPI_FINALIZE(IERR)
Завершение параллельной части приложения. Все последующие обращения к
любым процедурам МРI, в том числе к MPI_INIT, запрещены. К моменту вызова
MPI_FINALIZE каждым процессом программы все действия, требующие его участия в
обмене сообщениями, должны быть завершены.
4.2.2. Структура программ в MPI
Пример простейшей МРI-программы на языке Cи выглядит следующим образом:
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr;
printf("Before MPI_Init ...\n");
ierr=MPI_Init(&argc,&argv) ;
printf("Parallel section\n");
ierr=MPI_Finalize ();
printf("After MPI_Finalize\n") ; }
В зависимости от реализации MPI строчки «Before Mpi_Init» и «After Mpi_Finalize»
может печатать либо один выделенный процесс, либо все запущенные процессы
приложения. Строчку «Parallel section» должны напечатать все процессы. Порядок вывода
строк с разных процессов может быть произвольным.
В следующем примере каждый запущенный процесс печатает свой уникальный
номер в коммуникаторе mpi_comm_world и число процессов в данном коммуникаторе.
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
t ierr,size,rank;
MPI_Init(&argc,&argv);
ierr=MPI_Comm_size(MPI_COMM_WORLD, &size);
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);
printf("Process %i size %i\n",rank,size);
ierr=MPI_Finalize();
}
Cтрока, соответствующая вызову процедуры printf, будет выведена столько раз,
сколько процессов было порождено при запуске программы. Порядок появления строк
заранее не определен и может быть, вообще говоря, любым. Гарантируется только то, что
содержимое отдельных строк не будет перемешано друг с другом.
132
Определение характеристик таймера. В этой программе на каждом процессе
определяются две характеристики системного таймера: его разрешение и время,
требуемое на замер времени (для усреднения получаемого значения выполняется NTIMES
замеров). Также в данном примере показано использование процедуры MPI
GET PROCESSOR NAME.
#include <stdio.h> #include "mpi.h" -void main(int argc,char * argv) {
int ierr,rank,len,i,NTIMES=100;
char name[MPI_MAX_PROCESSOR_NAME];
double time_Start,time_finish,tick;
MPI_Init(&argc,&argv);
ierr=MPI_Comm_rank(MPI_COMM_WORLD, Srank);
ierr=MPI_Get_processor_name(name, &len);
name[len]=0;
tick=MPI_Wtick();
time_start=MPI_Wtime();
fnr (int n = 0:n<NTTMF,S;n + +) time finish=MPI Wtime
ierr=MPI_Comm_rank(MPI_Comm, &rank); printf("Processor %s, process %i: tick = %d, time
= %d\n",name,rank,tick,(time_finish-time_start)/(double)NTIMES; ierr=MPI_Finalize(); }
При передаче сообщений
использована
буферизация. Для буферизации
выделяется массив buf, после завершения пересылки он освобождается. Размер
необходимого буфера определяется размером сообщения (одно целое число – 4 байта)
плюс значение константы
MPI BSEND OVERHEAD.
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv)
{
const int BUFSIZE=MIP_BSEND_OVERHEAD+4;
unsigned char buf[BUFSIZE]; int rank,ierr,ibufsize,rbuf;
struct MPI_Status status; ierr=MPI_Init(&argc,&argv);
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank==0) {
ierr=MPI_Buffer_attach(buf,BUFSIZE);
ierr=MPI_BSend(&rank,1,MPI_INT,1,5,MPI_COMM_WORLD);
// sending variable rank
ierr=MPI_Buffer_detach(buf, BUFSIZE);
}
if (rank==l)
{ ierr=MPI_Recv(rbuf,1,MPI_INT,0,5,MPI_COMM_WIRLD,&status);
printf("Process 1 received %i from process
%i\n",rbuf,status.MPI SOURCE);
ierr=MPI_Finalize();
}
Ниже приведен пример программы, в которой нулевой процесс посылает сообщение
процессу с номером один и ждет от него ответа. Если программа будет запущена с
большим числом процессов, то реально выполнять пересылки все равно станут только
нулевой и первый процессы. Остальные процессы после их инициализации процедурой
MPI__Init напечатают начальные значения переменных а и b, после чего завершатся,
выполнив процедуру MPI_FINALIZE.
133
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr,size,rank; float a,b
MPI_Status status; ierr=MPI_Init();
ierr=MPI_Comm_size(MPI_COMMJ/TORLD, &size);
ierr=MPI_Comm_rank(MPI_COMM_WORLD, Srank); a=b=0;
if (rank==0) { ierr=MPI_Send(&b,1,MPI_FLOAT,1,5,MPI_COMM_WORLD);
ierr=MPI_Recv(&a,1,MPI_FLOAT,1,5,MPI_COMM_WORLD,Sstatus);
} else
if (rank==l)
{
a=2;
ierr=MPI_Recv(&b,1,MPI_FL0AT,0,5,MPI_COMM_WORLD,&status);
ierr=MPI Send(&a,1,MPI FLOAT,0,5,MPI COMM WORLD);
printf("Process %i a = %lf b = %lf\n",rank,a,b); ierr=MPI_Finalize();
}
В следующем примере каждый процесс с четным номером посылает сообщение
своему соседу с номером на единицу большим. Дополнительно поставлена проверка для
процесса с максимальным номером, чтобы он не послал сообщение несуществующему
процессу. Значения переменной b изменятся только на процессах с нечетными номерами.
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr,size,rank,a,b;
struct MPI_Status status;
ierr=MPI_Init ();
ierr=MPI_Comm_size(MPI_COMM_WORLD, &size);
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);
a=rank;
b=-l;
if (rank%2==0)
{
if (rank+Ksize)
ierr=MPI_Send(&a, 1, MPI_INT, rank+1, 5, MPI__COMM_WORLD) ;
}
else ierr=MPI_Recv(&b,l,MPI_INT,rank-l,5,MPI_C0MM_W0RLD,&status); printf ("Process %i a
= %i b = %i\n",rank,a,b) ; ierr=MPI_Finalize (); }
Процессы приложения в приводимой ниже программе разбиваются на две непересекающиеся примерно равные группы groupl и group2. При нечетном числе процессов в
группе group2 может оказаться на один процесс больше, тогда последний процесс из
данной группы не должен обмениваться данными ни с одним процессом из группы groupl.
С помощью вызовов процедуры MPI_Group_translate_ranks каждый процесс находит
процесс с тем же номером в другой группе и обменивается с ним сообщением через
коммуникатор MPl_COMM_WORLD при помощи вызова процедуры MPI_Sendrecv. В конце
134
программы не нужные далее группы уничтожаются с помощью вызовов процедур
MPI_GROUP_FREE.
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr,rank,i,size,sizel;
const int n=1000;
int a[4],b[4];
int ranks[128], rankl, rank2, rank3
MPI_Status status;
MPI_Group group,groupl,group2;
ierr=MPI_Init(Sargc,&argv);
ierr=MPI_Comm_size(MPI_COMM_WORLD,Ssize);
ierr=MPI_Comm_rank(MPI__COMM_WORLD, Srank) ;
ierr=MPI_Comm_group(MPI_COMM_WORLD, Sgroup);
sizel=size/2;
for (i=0;i<sizel;i++)
ranks[i]=i; ierr=MPI_Group_incl(group,sizel,ranks, &groupl);
ierr=MPI_Group_excl(group,sizel,ranks,&group2);
ierr=MPI_Group__rank (groupl, Srankl) ;
ierr=MPI_Group_rank(group2,&rank2);
kl==MPI_UNDEFINED) // we are in second half
{ if (rank2<sizel)
ierr=MPI_Group_translate_ranks(groupl,1,rank2,group,&rank3); else
rank3=MPIJJNDEFINED;
}
else // in first half ierr=MPI_Group_translate_ranks(group2,1,rankl,group,&rank3);
a[0]=rank; a[1]=rankl; a [2]=rank2; a[3]=rank3; if (rank3!=MPI_UNDEFINED)
ierr=MPI_Sendrecv(a,4,MPI_INT,гапкЗ,1, b, 4,
MPI_INT,гапкЗ,1,MPI_COMM_WORLD,Sstatus);
ierr=MPI_Group_free(group) ;
ierr=MPI_Group_free(groupl);
ierr=MPI_Group_free(group2); printf ( "Process %i
a=[",rank); for (int n=0;n<4;n++) printf("%i ",a[i]);
printf ("] b=[");
for (int n=0;n<4;n++) printf ("%i ",b[i]); printf("]\n");
ierr=MPI Finalize ();
4.2.3. Определение структуры приходящего сообщения
Иллюстрация применения процедуры MPI_Probe для определения структуры
приходящего сообщения. Процесс 0 ждет сообщения от любого из процессов 1 и 2 с
одним и тем же тегом. Однако посылаемые этими процессами данные имеют разный тип.
Для того чтобы определить, в какую переменную помещать приходящее сообщение,
процесс сначала при помощи вызова MPI_Probe определяет, от кого же именно поступило
это сообщение. Следующий непосредственно после MPI_Probe вызов MPI_Recv
гарантированно примет нужное сообщение, после чего принимается сообщение от
другого процесса.
135
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int rank,ierr,ibuf;
struct MPI_Status status;
float rbuf;
ierr=MPI_Init();
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);
rbuf=l.0F*rank;
switch (rank)
{
case 1: {
ierr=MPI_Send(&ibuf,1,MPI_INT,0,5,MPI_COMM_WORLD);
break;
}
case 2: {
ierr=MPI_Send(&rbuf,l,MPI_FLOAT,0,5,MPI_COMM_WORLD); break;
}
case 0: {
ierr=MPI_Probe(MPI_ANY_SOURCE,5,MPI_COMM_WORLD,Sstatus); if
(status.MPI_S0URCE==1)
// message from process 1 received first {
ierr=MPI_Recv(&ibuf,1,MPI_INT,1,5,
MPI_COMM_WORLD,&status);
ierr=MPI_Recv(&rbuf,1,MPI_FLOAT,1,5,
MPI_COMM_WORLD,Sstatus);
} else // message from process 2 received first if
(status.MPI_S0URCE==2) // ignore messages from other processes
{ ierr=MPI_Recv(&rbuf,1,MPI_FL0AT,
l,5,MPI_C0MM_W0RLD,&status);
ierr=MPI_Recv(&ibuf,1,MPI_INT,
l,5,MPI_C0MM_W0RLD,&status);
} printf("Process 0 recv %i from process 1 %lf
from process 2\n",ibuf,rbuf); break;
ierr=MPI_Finalize(); ‘}
4.2.4. Определение базовых характеристик коммуникационной сети
Приведена программа, в которой моделируется последовательный обмен
сообщениями между двумя процессами, замеряется время на одну итерацию обмена,
определяется зависимость времени обмена от длины сообщения. Таким образом,
определяются базовые характеристики коммуникационной сети параллельного
компьютера: латентность (время на передачу сообщения нулевой длины) и максимально
достижимая пропускная способность (количество мегабайт в секунду) коммуникационной
сети, а также длина сообщений, на которой она достигается. Константа NMАХ задает
ограничение на максимальную длину посылаемого сообщения, а константа NTIMES
определяет количество повторений для усреднения результата. Сначала посылается
сообщение нулевой длины для определения латентности, затем длина сообщений
удваивается, начиная с посылки одного элемента типа float[8].
136
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr,rank,size,i,n,lmax,NTIMES=10;
const int NMAX=1000 0 00;
double time_start,time,bandwidth,max;
float a[NMAX*8]; // equal to real*8 a[NTIMES] at fortran
struct MPI_Status status;
ierr=MPI_Init();
ierr=MPI_Comm_size (MPI_COMM__WORLD, &size) ;
ierr=MPI_Comm_rank(MPI_COMM_WORLD, Srank);
time_start=MPI_Wtime();
n=0;
nmax=lmax=0;
while (n<=NMAX)
{
time_start=MPI_Wtime(); for (int
i=0;i<NTIMES;i++) {
if (rank==0)
{ ierr=MPI_Send(&a,8*n,MPI_FLOAT, 1, 1, MPI_COMM_WORLD) ;
ierr=MPI_Recv(&a, 8*n, MPI__FLOAT, 1, 1, MPI_COMM_WORLD, &status) ;
}
if (rank==l)
ierr=MPI_Recv(&a,8*n,MPI_FLOAT,0,1,MPI_COMM_WORLD,sstat us) ;
ierr=MPI_Send(&a,8*n,MPI_FLOAT,0,l,MPI_COMM_WORLD); } }
time=(MPI_Wtime()-time_start)/(2*NTIMES); // this is time
for one way transaction
/*
Bandwidth = count of MBytes/time
count of MBytes= count of bytes/ 1M
(1M= 1024*1024 = 2Л10*2Л10=2**10 on fortran dialect :)
*/
bandwidth=((double)8*n*sizeof(float))/ (1024*1024)/time;
if (max<bandwidth)
{
max=bandwidth;
lmax=8*n*sizeof(float); } if
(rank==0)
{
if (!n) printf("Latency = %10.4d seconds\n", time) ; else printf("%i bytes sent,
bandwidth = %10.4d MB/.s", 8*n*sizeof (float) ,bandwidth) ; } n=!n?l:2*n; // if (n==0)
n=l; else n*=2;
}
// Finally print maximum bandwidth
if (rank==0)
printf("Max bandwidth = %10.4d MB/s, length = %i
bytes\n",lmax);
ierr=MPI_Finalize(); }
137
4.2.5 Анализ тупиковых ситуаций при обмене
Процессы обмена сообщениями с ближайшими соседями в соответствии с
топологией кольца при помощи неблокирующих операций показаны в фрагменте
нижеприведенной программы. Заметим, что использование для этих целей блокирующих
операций может привести к возникновению тупиковой ситуации.
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr,rank,size,prev,next,buf[2];
MPI_Request reqs[4];
MPI_Status status[4];
ierr=MPI__Init();
ierr=MPI_Comm_size(MPI_COMM_WORLD, &size);
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank)/
prev=rank==0?size-l:rank-1;
next=rank==size-l?0:rank+1;
ierr=MPI_Irecv(&buf[0],1,MPI_INT,prev,5,
MPI_COMM_WORLD,Sreqs[0]);
ierr=MPI_Irecv(&buf[1],1,MPI_INT,next,6,
MPI__COMM_WORLD, Sreqs[1] );
ierr=MPI_Isend(&rank,1,MPI_INT,prev,6,
MPI_COMM_WORLD,&reqs[2]);
ierr=MPI_Isend(&rank,1,MPI_INT, next, 5, _W0RLD, &size) ;
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank!=0) //this is slave while
(1)
{
slave(N);
ierr=MPI_Send(a,N,MPI_DOUBLE,0,5,MPI_COMM_WORLD);
} else // if this is process with index 0 (master)
{
for (int i=l;i<size-l;i++)
ierr=MPI_Irecv(&a[i],N,MPI_DOUBLE,i,5,MPI_COMM_WORLD,&req[i]);
while (1)
MPI_COMM_WORLD,&reqs[3]);
ierr=MPI__Waitall (4 , reqs, status) ;
printf ( "process %i prev=%i
next=%i\n",buf[0],buf[1]); }
Схема
использования
процедуры
MPI_Waitsome
для
организации
коммуникационной схемы <master-slave> (все процессы общаются с одним выделенным
процессом). демонстрируется в следующем примере. Все процессы, кроме процесса 0, на
каждой итерации цикла определяют с помощью вызова процедуры slave свою локальную
часть массива а, после чего посылают ее главному процессу. Процесс 0 сначала
инициализирует неблокирующие приемы от всех остальных процессов, после чего
дожидается прихода хотя бы одного сообщения. Для пришедших сообщений процесс 0
вызывает процедуру обработки master, после чего снова выставляет неблокирующие
приемы. Таким образом, процесс 0 обрабатывает те порции данных, которые готовы на
данный момент. При этом для корректности работы программы нужно обеспечить, чтобы
процесс 0 успевал обработать приходящие сообщения, то есть, чтобы процедура slave
138
работала значительно дольше процедуры master (в противном случае и распараллеливание
не имеет особого смысла). Кроме того, в примере написан бесконечный цикл, поэтому для
конкретной программы нужно предусмотреть условие завершения.
#include' <stdio.h>
#include "mpi.h"
const int N=1000,MAXPROC=128;
double a[MAXPROC] [N];
void slave(int n)
{ // something
}'
void master(int n)
{
}
void main(int argc,char * argv[])
{
int ierr,rank,size; int
num,indexes[MAXPROC]; MPI_Request
req[MAXPROC]; MPI_Status
statuses[MAXPROC]; ierr=MPI Init();
ierr=MPI_Comm_size(MPI_C0MM
{
ierr=MPI_Waitsome(size-1, req,&num,indexes,statuses); for (int i=l;i<num;i++)
{
master (indexes[i])/
ierr=MPI_Irecv(a[indexes[i]],N,MPI_DOUBLE,
indexes[i],5,MPI_COMM_WORLD,req[indexes[i]]); } } } ierr=MPI_Finalize(); }
4.2.6. Организация передачи-приёма сообщений без блокировки
Демонстрация применениея неблокирующих операций для реализации
транспонирования квадратной матрицы, распределенной между процессами по строкам,
приведена ниже. Сначала каждый процесс локально определяет nl строк массива а. Затем
при помощи неблокирующих операций MPI_Isend и MPI_Irecv инициализируются все
необходимые для транспонирования обмены данными. На фоне начинающихся обменов
каждый процесс транспонирует свою локальную часть массива а. После этого процесс при
помощи вызова процедуры MPI_Waitany дожидается прихода сообщения от любого
другого процесса и транспонирует полученную от данного процесса часть массива а.
Обработка продолжается до тех пор, пока не будут получены сообщения от всех
процессов. В конце исходный массив а и транспонированный массив b распечатываются.
#include <stdio.h>
#include "mpi.h"
const int N=9;
double a[N][N],b[N][N];
void work(int n,int nl,int size,int rank)
{
int i,j,ii,jj,ir,irr;
const int MAXPROC=64;
char * a,*b,c;
MPI_Status status;
139
MPI_Request req[MAXPROC*2] ; //
creating arrays a=new char [nl*n]; b=new
char [nl*n]; //ok
for (i=l;i<nl;i++)
for (j=l;j<n;j++) { ii=i+rank*nl;
if (ii<=n) a[i*n+j]=100*ii+j; } for (ir=0;ir<size-l;ir++) if (ir!=rank)
ierr=MPI_Irecv(&b[l*n+ir*nl+l],nl*nl,MPI_DOUBLE,
ir,MPI_ANY_TAG,MPI_COMM_WORLD,&req[ir+l] ) ; req[rank+1]=MPI_REQEST_NULL; for
(ir=0;ir<size-l;ir++) if (ir!=rank)
ierr=MPI_Isend(a[l*n+ir*nl+l],nl*nl,MPI_DOUBLE,ir MPI__COMM_WORLD,
&req[ir+1+size] ) ; ir=rank;
for (i=l;i<nl;i++) {
ii=i+ir*nl;
for (j=i + l;j<nl;j++)
{
jj=j+ir*nl; b[i*n+jj]=a[j*n+ii]; b[j*n+ii]=a[i*n+jj]; }
b [ i*n+i i] =a [i*n+ii.] ; }
for (irr=l;irr<size-l;irr++)
{
ierr=MPI_Waitany(size,req,ir, status) ; ir=ir-l; for (i=l;i<nl/i++)
{
ii=i+ir*nl;
for (j=i + l;j<nl;j++)
{
jj=j+ir*nl; c=b[i*n+jj];
b[i*n+jj] =b[j*n+ii]
; b[ j*n+ii]=c;
for (i=l;i<nl;i++) for
(j=l;j<N;j++) {
ii=i+rank*nl;
if (ii<=n) printf("Proce ss %i : a (%i,%i)= %4.4d,
b(%i,%i)=%4.4.d\n",rank,ii,j,a[i*n+j],ii,j , b[i*n+j]);
} // deleting
arrays
delete a;
delete b; } void main(int argc,char *
argv[])
{
int ierr,rank,size,nl,i, j;
ierr=MPI_Init();
ierr=MPI_Comm_size(MPI_COMM_WORLD, &size) ;
ierr=MPI_Comm_rank,(MPI_COMM_WORLD, &rank) ; nl=(Nl)/size+1; work(N,nl,size,rank); ierr=MPI Finalize();
В следующем примере операции двунаправленного обмена с соседними процессами
в кольцевой топологии производятся при помощи двух вызовов процедуры MPI_Sendrecv.
При этом гарантированно не возникает тупиковой ситуации.
include <stdio.h>
#include "mpi.h" void
main() {
int ierr,rank,size,prev,next,buf [2];
140
MPI_Status statusl,status2;
ierr=MPI_Init();
ierr=MPI_Comm_size(MPI_COMM_WORLD, &size);
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);
prev=rank==0?size-l:rank-l;
next=rank==size-l?0:rank+1;
ierr=MPI_Sendrecv(&rank,1,MPI_INT,prev,6,&buf[2],1,MPI_INT,
next, 6,MPI_C0MM_W0RLD,&status2);
ierr=MPI_Sendrecv(&rank,1,MPI_INT,next,5,&buf[1],1,MPI_INT,
prev, 5,MPI_C0MM_W0RLD,sstatusl);
printf("Process %i prev=%i next = %i\n" , rank,buf[0],buf[1]); ierr=MPI_Finalize (); }
4.2.7. Реализация отложенных запросов на взаимодействие
В следующем примере функциональность процедуры MPI_Barrier моделируется
при помощи отложенных запросов на взаимодействие. Для усреднения результатов
производится NTIMES операций обмена, в рамках каждой из них все процессы должны
послать сообщение процессу с номером 0, после чего получить от него ответный сигнал,
означающий, что все процессы дошли до этой точки в программе. Использование
отложенных запросов позволяет инициализировать посылку данных только один раз, а
затем использовать на каждой итерации цикла. Далее время на моделирование
сравнивается со временем на синхронизацию при помощи самой стандартной процедуры
MPI_Barrier.
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr,rank,size,i,it;
const int MAXPROC=128,NTIMES=10000;
int
ibuf[MAXPROC];
double
time_start,time_finish;
MPI_Request req[2*MAXPR0C];
MPI_Status statuses[MAXPROC];
ierr=MPI_Init(&argc,&argv);
ierr=MPI_Comm_size(MPI_COMM_WORLD,&size);
ierr=MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if (rank==0) // process number 0
{ for (i=l;i<size;i++)
{ ierr=MPI_Recv_init(Sibuf[i],0,MPI_INT,i,5,MPI_COMM_WORLD, &req[i]) ;
ierr=MPI_Send_init(Srank,0,MPI_INT,i,6,MPI_COMM_WORLD,&req[size + i] ) ;
}
time_start=MPI_Wtime();
for (it=0;it<NTIMES;it++)
{
// waiting receive
ierr=MPI_Startall(size-1, req) ;
ierr=MPI_Waitall(size-1, req,Sstatuses);
// waiting send
ierr=MPI_Startall(size-1, &req[size + l]) ;
ierr=MPI_Waitall(size-1, &req[size + l],Sstatuses);
141
}
}
else // not 0 process
{
ierr=MPI_Recv_init(Sibuf[1],0,MPI_INT,0,6,MPI_COMM_WORLD,&req[l]);
ierr=MPI_Send_init(&rank,0,MPI_INT,0,5,MPI_COMM_WORLD, &req[2] ) ;
time_start=MPI_Wtime();
for (it=0;it<NTIMES;it++)
{
// waiting receive
ierr=MPI_Start(&req[2]);
ierr=MPI_Wait(&req[2],statuses);
// remember, statuses==&statuses[0]
// waiting send
ierr=MPI_Start(&req[l]);
ierr=MPI_Waitall(&req[1],statuses
);
}
}
time_finish = MPI_Wtime()time_start ; printf("Rank = %I
barrier time = %d (double)
(time__finish) /NTIMES) ;
ierr=MPI_Finalize(); }
4.2.8. Сравнительная оценка различных способов обмена данными
Ниже производится сравнение операции глобального суммирования при помощи
схемы сдваивания с использованием пересылок данных типа точка-точка. Эффективность
такого моделирования сравнивается с использованием коллективной операции
MPI_Reduce.
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr,rank,size,nproc,i; const int n=1000000; double time_start,time_finish;
double a[n],b[n],с[n]; MPI_Status status; ierr=MPI_Init(&argc,&argv);
ierr=MPI_Comm_size(MPI_COMM_WORLD,&size);
ierr=MPI_Comm_rank(MPI_COMM_WORLD,Srank); nproc=size; for
(i=l;i<=n;i++) a[i-1]=i/(double)size; // in с indexing starts from 0;
ierr=MPI__Barrier (MPI_COMM_WORLD) ;
time_start=MPI_Wtime(); for ( i = 0 ; i < n ; i + + )
c [ i ] = a [ i ] ; while
(nproOl) {
if (rank<nproc/2)
{
ierr=MPI_Recv( b , n,MPI_DOUBLE,nproc-rank1,1,MPI_C0MM_W0RLD,&status); for ( i = 0 ; i < n ; i + + )
с[i]+=b [ i];
}
142
else if (rank<nproc) ierr=MPI_Send(c,n,MPI_DOUBLE,nproc-rank1,1,MPI_C0MM_W0RDL); nproc/=2; } for (i=0;i<n/i++)
b[i]=c[i]; time_finish=MPI_Wtime-time_start;
if (rank==0) printf("model b[l]=%d rank=%i model time=%d \n", b [0],rank,time_finish); for
(i=l;i<=n;i++) .
a[i-1]=i/(double)size;
ierr=MPI_Barrier(MPI_C0MM_W0RLD);
time_start=MPI_Wtime();
ierr=MPI_Reduce(a,b,n,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
time_finish=MPI_Wtime-time_start; if (rank==0) printf("reduce b[l]=%d rank=%i reduce
time=%d \n", b[0] , rank,time_finish); ierr=MPI Finalize ();
4.2.9. Использование глобальных операций в MPI
Следующий пример демонстрирует задание пользовательской функции для
использования в качестве глобальной операции. Задается функция smod5, вычисляющая
поэлементную сумму по модулю 5 векторов целочисленных аргументов. Данная функция
объявляется в качестве глобальной операции ор в вызове процедуры MPI_Op_create, затем
используется в процедуре MPI_Reduce, после чего удаляется с помощью вызова
процедуры MPI_OP_FREE.
#include <stdio.h>
#include "mpi.h"
int smod5(int * a,int * b,int cnt,int type)
{
for (int i=0;i<cnt;i++)
b[i] = ( b [ i ] + a [ i ]
) % 5 ; return
MPI_SUCCESS;
}
void main(int argc,char * argv[])
{
int ierr,rank,i,op;
const int n=1000;
inta[n],b[n];
ierr=MPI_Init(&argc,&argv);
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank) ;
for (i=0;i<n;i++) a[i]=i+rank+l; // in fortran first elementh will contain 1 // addition
of 1 makes similar result in С
printf ("Process %i, a[0]=%i\n" , rank, a[0] ) ;
ierr=MPI_Op_create(smod5,1, &op) ;
ierr=MPI_Reduce(a,b,n,MPI_INT,op,0,MPI_COMM_WORLD);
ierr=MPI__Op_free(op);
if (rank==0) printf("b[0]=%i\n",b[0]);
ierr=MPI_Finalize () ;
4.2.10. Взаимодействие процессов в MPI
С помощью следующей программы создается один новый коммуникатор
comm_revs, в который входят все процессы приложения, пронумерованные в обратном порядке. Когда коммуникатор становится ненужным, он удаляется при помощи вызова
143
процедуры MPl_COMM_FREE. Так можно использовать процедуру
перенумерации процессов.
MPI_COMM_SPLIT
для
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr,rank,size;
int rankl;
MPI_Comm comm_revs;
ierr=MPI__Init (&argc, &argv) ;
ierr=MPI_Comm_size(MPI_COMM_WORLD, Ssize) ;
ierr=MPI_Comm_rank(MPI_COMM_WORLD,Srank);
ierr=MPI__Comm_split (MPI_COMM_WORLD, 1, size-rank, &comm__revs) ;
ierr=MPI_Comm_rank(comm_revs,&rankl);
printf("Rank = %i, rankl = %i\n",rank,rankl);
ierr=MPI_Finalize();
Следующая программа иллюстрирует создание графовой топологии comm_graph
для общения процессов по коммуникационной схеме master-slave. Все процессы в рамках
данной топологии могут общаться только с нулевым процессом. После создания топологии
с помощью вызова процедуры MPI_GRAPH_CREATE каждый процесс определяет количество
своих непосредственных соседей в рамках данной топологии
(с помощью вызова
процедуры MPI_Graph_neighbors_count) и ранги процессов-соседей (с помощью вызова
процедуры MPI_Graph_neighbors). После этого каждый процесс может в рамках данной
топологии обмениваться данными со своими непосредственными соседями, например, при
помощи вызова процедуры MPI_Sendrecv.
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr, rank, rankl, i, size;
const int MAXPROC = 1 2 8, MAXEDGES = 512;
int a,b;
MPI_Status status;
MPI_Comm comm_graph;
int index[MAXPROC];
int edges[MAXPROC];
int num,neighbors[MAXPROC];
ierr=MPI__Init (&argc, &argv) ;
ierr=MPI_Comm_size(MPI_COMM_WORLD,Ssize);
ierr=MPI_Comm_rank(MPI_COMM_WORLD,&rank);
for (i = 0; Ksize; i++)
index[i]=size+i-l; for
(i=0;i<size-l;i++)
{
edges[i]=i; edges[size+i-l]=0; }
ierr=MPI_Graph_create(MPI_COMM_WORLD,size,index,edges,1,&comm_graph);
ierr=MPI_Graph_neighbors_count(comm_graph,rank,&num);
ierr=MPI_Graph_neighbors(comm_graph,rank,num,neighbors); for (i=0;i<num;i++) {
144
ierr=MPI_Sendrecv(rank,1,MPI_INT,neighbors[i],1,Srankl,1,
MPI_INT,neighbors[i],1,comm_graph,Sstatus); printf ( "Process %i .communicate with process
%i\n" , rank, rankl) ; } ierr=MPI Finalize ();
Использование производного типа данных показан в следующем примере.
Производный тип данных применён для перестановки столбцов матрицы в обратном
порядке. Тип данных matr_rev, создаваемый процедурой MPI_TYPE_VECTOR, описывает
локальную часть матрицы данного процесса в переставленными в обратном порядке
столбцами. После регистрации этот тип данных может использоваться при пересылке.
Программа работает правильно, если размер матрицы N делится нацело на число
процессов приложения.
#include <stdio.h> #include
"mpi.h"
void work(double a[ N ] [ N ] ,double b [ N ] [ N ] , i n t n, const int
n l , i n t s i z e , i n t rank)
{
int ierr, rank, size, n, nl, ii; int i,j;
MPI_Datatype matr_rev; MPI__Status
status; for (j=0;j<nl;j++) for
(i=0;i<nl;i++) {
b[i] [j]=0; ii=j+rank*nl; a [i] [j]=100*ii+i; } ierr=MPI_Type_vector(nl,n,n,MPI_DOULBE,&matr_rev); ierr=MPI_Type_commit(&matr_rev); ierr=MPI_Sendrecv (a
[1] [nl],l,matr_rev,size-rank-1, l,b,nl*n,MPI_DOUBLE,size-rank1,1,MPI_COMM_WORLD,Sstatus); for (j=0;j<nl;j++) for (i=0;i<n;i++)
printf ("Process %i : %i %i %d %d\n",rank, j+rank*nl,i,a[i] [j] ,b[i] [j] ) ; } void
main(int argc,char * argv[])
{
int ierr, rank, nl, size;
const int N=8;
double a[N] [N],b[N] [N];
ierr=MPI_Init(&argc,&argv);
ierr=MPI Comra size(MPI COMM WORLD,&size) ;
ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank) ; nl =
(N-l)/size+1; work(a,b,N,nl,size,rank); ierr=MPI_Finalize ()
;}
Следующий пример иллюстрирует трансляционный способ обмена информацией. Массив
buf используется в качестве буфера для упаковки 10 элементов массива а типа float и 10
элементов массива b типа character. Полученное сообщение пересылается процедурой
MPI_BCAST от процесса 0 всем остальным процессам, полученное сообщение распаковывается при помощи вызовов процедур MPI_UNPACK.
#include <stdio.h>
#include "mpi.h"
void main(int argc,char * argv[])
{
int ierr, rank, position;
float a[10];
char b[10],buf[100];
ierr=MPI_Init(Sargc,Sargv);
145
ierr=MPI_Comm_rank(MPI_COMM_WORLD,Srank);
for (i=0;i<10;i++)
{
a[i]=rank+l;
if (rank==0) b[i]='a'; else
b[i]='b'; }
position=0; if
(rank==0)
{
ierr=MPI_Pack(a,10,MPI_FLOAT,buf,100,Sposition,MPI_COMM_WORLD);
ierr=MPI_Pack(b,10,MPI_CHAR,buf,100,Sposition,MPI_COMM_WORLD);
ierr=MPI_Bcast(buf,100,MPI_PACKED,0,MPI_COMM_WORLD); }
else { ierr=MPI_Bcast(but,100,MPI_PACKED,0,MPI_COMM_WORLD);
position=0;
ierr=MPI_Unpack(buf,100,position,a,10,MPI_FLOAT,MPI_COMM_WORLD);
ierr=MPI_Unpack(buf, 100, position, b, 10 , MPI_CHAR, MPI_COMM__WORLD) ; }
printf("Process %i a=[",rank);
for (int n=0;n<10;n++) printf ("%i ",a[i]);
printf("] b=[");
for (int n=0;n<10;n++) printf("%i ",b[i]);
printf ("]\n");
ierr=MPI Finalize();
4.2.11. Вопросы к раделу 4.2
1. Можно ли в процессе работы МРI-программы порождать новые процессы,
если в какой-то момент появились свободные процессоры?
2. Может ли МРi-программа продолжать работу после аварийного завершения
одного из процессов?
3. Определить, синхронизованы ли таймеры разных процессов конкретной
системы.
4. Чем коллективные операции отличаются от взаимодействий типа точка- точка?
5. Верно ли, что в коллективных взаимодействиях участвуют все процессы
приложения?
6. Могут ли возникать конфликты между обычными сообщениями, посылаемыми
процессами друг другу, и сообщениями коллективных операций? Если да, как они
разрешаются?
7.Какие группы процессов существуют при запуске приложения?
8. Могут ли группы процессов иметь непустое пересечение, не совпадающее ни с
одной из них полностью?
9. Могут ли обмениваться данными процессы, принадлежащие разным
коммуникаторам ?
10. Может ли в какой-то группе не быть процесса с номером 0?
15. Какие коммуникаторы существуют при запуске приложения?
12. Обязана ли виртуальная топология повторять физическую топологию
целевого компьютера?
13. Любой ли коммуникатор может обладать виртуальной топологией?
14. Может ли процесс входить одновременно в декартову топологию и в
топологию графа?
15. В чем преимущества и недостатки использования пересылок упакованных
данных по сравнению с пересылками данных производных типов?
146
ГЛАВА 5. Граф-схемы параллельных алгоритмов
5.1. Представление параллельных алгоритмов в виде граф-схем
5.1.1. Преобразование последовательных алгоритмов в параллельные
До появления вычислительных систем основным инструментом для решения задач
с помощью ЭВМ являлся последовательный алгоритм (программа), который представлял
собой совокупность операторов с указанием последовательности их выполнения. В
каждый момент времени выполняется только один оператор, и существуют определённые
правила перехода от исполнения одного оператора к исполнению последующих (одного
или нескольких). В последовательном алгоритме следующим за исполняемым
оператором, начиная с первого, выполняется оператор, вслед за ним стоящий, если
исполняемый оператор не является оператором условного или безусловного перехода.
Условный или безусловный оператор может передать управление любому оператору
алгоритма. Алгоритм, в котором производится распараллеливание на уровне
программных модулей, должен состоять из программных модулей, которые могут иметь
несколько входов и несколько выходов.
Определение 5.1.1. Алгоритм, в котором существуют операторы или модули,
передающие управление одновременно нескольким операторам и/или модулям,
называется параллельным.
Создание средств отображения схем параллельных алгоритмов наиболее полно
представлены в ГОСТ 19.701-90 ЕСПД. СХЕМЫ АЛГОРИТМОВ, ПРОГРАММ,
ДАННЫХ И СИСТЕМ. В этом ГОСТе приведён фрагмент параллельной программы,
приведённый на рисунке 5.1.1.
A
C
B
D
E
F
Рисунок 5.1.1. Фрагмент параллельного алгоритма в соответствии с
ГОСТ 19.701-90 ЕСПД
В примечании к этому рисунку сказано, что «процессы С, D и Е не могут начаться
до тех пор, пока не завершится процесс А; аналогично процесс F должен ожидать
завершения процессов В, С и D, однако процесс С может начаться и (или) завершиться
прежде, чем соответственно начнется и (или) завершится процесс D».
Такой подход существенно ограничивает возможности параллельного
программирования и естественным образом продолжает идеи и методы представления
последовательных алгоритмов. Необходимо убрать параллельные линии из схемы
алгоритмов, так как они затемняют эту схему и сужают функциональные возможности
процессов параллельных алгоритмов. Если соединить связями процесс A c процессами C,
147
D и E, то по этим связям можно передавать различные результаты обработки данных.
Времена окончания передачи данных так же могут быть различны. Аналогичные
замечания можно сделать относительно процесса F. Более подробно эти замечания будут
рассмотрены при представлении схем алгоритмов с помощью граф-схем алгоритмов.
Распараллеливание последовательных алгоритмов предполагает разбиение этого
алгоритма на параллельные ветви (модули) Mi, i  {1,2, ..., n}, где n – число параллельных
ветвей. Для каждой параллельной ветви имеются множество его входных данных и
множество выходных (вырабатываемых модулем Mi) данных Di. Два модуля Mi и Mj могут
выполняться независимо и параллельно, если между ними нет зависимости по данным.
Эти условия гарантируют, что выходные данные, например, модуля Mi не могут затереть
входные данные модуля Mj и, соответственно, выходные данные модуля Mj не могут
затереть входные данные модуля Mi. Эти требования могут быть распространены на
произвольное число модулей, которые могут выполняться независимо и параллельно. Не
менее важным фактором при организации параллельных вычислений является
соблюдение очерёдности выполнения программных модулей. С одной стороны,
соблюдение очерёдности выполнения программных модулей гарантирует правильность
поступления исходных данных для обработки в программные модули, с другой –
построение соответствующих линейных участков алгоритма в заданном порядке.
Сохранение требуемой последовательности выполнения модулей в параллельных
алгоритмах может быть обеспечено двумя способами. Первый способ основан на знании
времён выполнения модулей и последовательности их выполнения, используя которые
можно построить требуемый план выполнения модулей. Второй способ основан на
использовании синхронизирующих примитивов, регулирующих доступ совокупности
модулей к совместно используемым элементам памяти.
При разработке схем параллельных алгоритмов рассмотрен метод построения
граф-схем алгоритмов на базе ранее разработанных последовательных алгоритмов,
созданных в соответствии с ГОСТ 19.003-80 ЕСПД,
ГОСТ 19.701-90 ЕСПД.
Распараллеливание предполагается на уровне программных модулей. Вначале создаётся
схема алгоритма, как это делалось для традиционных вычислительных средств без учёта
оператора параллельных вычислений, включающая только процедуры и функции. Такую
схему алгоритма, не противоречащую выше перечисленным ЕСПД, и будем относить к
классу последовательных алгоритмов.
Учитывая, что ввод-вывод данных рассматривается в ВС как самостоятельный
процесс, будем считать, что в рассматриваемой схеме алгоритма ввод-вывод данных уже
осуществлён, а обмен данными будет осуществляться только через аппарат формально фактических параметров. Исключаются также терминаторы начала и конца программы.
Затем с помощью предлагаемой ниже процедуры схема последовательного алгоритма
разбивается на участки. Участки бывают трёх видов: начальный, внутренний и конечный.
В нижеприведенных определениях под логическим модулем понимаются операторы,
функции и (или) процедуры языков программирования, имеющих два, три или более
выходов и выдающие результаты работы только на одном из выходов в зависимости от
поступивших на их вход данных.
Определение 5.1.2. Начальный участок – это последовательность модулей,
заключённых между первым оператором после терминатора начала алгоритма, и
первым встретившимся логическим модулем. При отсутствии логических модулей - это
последовательность модулей, заключённых между первым оператором после
терминатора начала алгоритма и последним оператором перед терминатором его
конца.
Определение 5.1.3. Внутренний участок – это последовательность модулей,
заключённых между двумя очередными логическими операторами.
148
Определение 5.1.4. Концевой участок – это последовательность модулей,
заключённых между логическим модулем и терминатором конца алгоритма.
Терминаторы начала и конца алгоритма в создаваемые участки не попадают.
Примечание. Концевых участков может быть несколько – по числу терминаторов
конца алгоритма.
Перенумеруем модули участков в порядке их следования, включая только
вычислительные и логические модули. Пусть, например, программу зададим в виде:
N, k11, k12 , ..., k1n1, L1T, k2t1, k2t2 ,…, k2tn, L1F, k2f1, k2f2, …,k2fn2,
L2T, k3t1, k3t2, …, k3tn3, L2F, k3f1, k3f2, …, k3fn2, L3T, …, kgm, …, F,
(5.1.1)
где N – терминатор начала программы; kji – программный модуль j – ого участка с
номером i; Lj-1T – конец участка j-1 и начало j – ого участка, образованного логической
ветвью «TRUE»; Lj-1F – конец участка j-1 и начало j – ого участка, образованного
логической ветвью «FALSE»; kgm - программный модуль m–ого участка с номером g;
F – терминатор конца программы. Начальный участок алгоритма обозначим Uнач,
внутренний участок – Uвн, концевой участок – Uкон.
Примечание: в выражении (5.1.1) в логических операторах использованы два
выхода, хотя использование операторов на большее количество выходов никак не
влияет на способ разбиения алгоритма на участки, а только усложняет его.
Образуются участки программы: U1, U2, U3, …, Um. Пример построения
участков дан на рисунке 5.1.2. Участок U1 образует множество номеров операторов:
{2, 3, 4}, U2 – { 4, 5, 6, 7}, U3=Uкон – { 4, 8, 9, 10}. Затем осуществим перенумерацию
участков Для участка U1 номер 1 порождает оператор с номером 2, номер 2– оператор
с номером 3, номер 3 – оператор с номером 4.Таким образом, Uнач={1, 2, 3}, Для
участка U2 номер 1 порождает оператор условного перехода с номером 4, номер 2 –
оператор с номером 3, номер 3 – оператор с номером 6, номер 4 – оператор с номером
7. .Таким образом, Uкон={1, 2, 3, 4}. Для участка U3 номер 1 порождает оператор
условного перехода с номером 4, номер 2 – оператор с номером 8, номер 3 – оператор
с номером 9, номер 4 – оператор с номером 10. Таким образом, Uкон={1, 2, 3, 4} и
создаётся два конечных участка. Так как в участках операторы нумеруются
независимо, то последовательность нумерации логических операторов может быть
произвольная. Для внутренних участков множество номеров операторов будет
содержать на первом и последнем месте номера соответствующих логических
операторов.
Рис.5.1.2. Схема классического последовательного алгоритма
149
Разбиение программы на участки, используя в качестве разделителя,
логический оператор объясняется тем, что выполнение того или иного участка зависит
от значений логических переменных. Зависимость по данным определяется по
параметрам процедур и (или) функций. Использование глобальных параметров
различных уровней при таком подходе невозможно. В такой программе должно быть
произведено преобразование. Передача данных через глобальные параметры должна
быть заменена передачей данных с помощью аппарата формально – фактических
параметров. Распознавание зависимости по данным между программными модулями
можно осуществить, используя присвоение выходным параметрам программных
модулей специальных имён, используя металингвистические формулы (5.1.2). При
этом метод выбора специальных имён не должен существенно ограничивать
возможности программистов. В качестве такого метода предлагается создавать имена
выходных параметров, используя следующие соотношения, составленные на
основании нотации Бекуса [31]:
<имя выходного параметра программного модуля> ::= >
<префикс>< имя программного модуля
<буквы> ::= |A|B|…|Z|
<префикс> ::= <буквы> |<буквы> <префикс>
(5.1.2)
Метапеременная <буквы> представлена терминальными символами – буквами
латинского алфавита. Метапеременная <имя программного модуля> определяется по
правилам языка программирования, на котором будет написан соответствующий
программный модуль.
Назовем связи, входящие в вычислительные модули или логические блоки,
входными; выходящие из этих модулей или блоков – выходными. Будем полагать, что
в каждый блок может входить и выходить несколько связей. Результаты работы
модуля передаются через параметры, формируемые в соответствии с
выражением (5.1.2). Так, например, на рисунке 5.1.2 модуль с именем АВ передает
результаты своих вычислений через параметр SAB. Модуль DE использует данные,
формируемые модулем АВ, что означает, что модуль DE зависит по данным от модуля
АВ и т.д.
Сущность преобразования последовательного алгоритма в параллельный
заключается в следующем: в пределах участка проверяется зависимость нижестоящих
программных модулей по параметрам от вышестоящих. Далее, если зависимость
имеется, то программные модули не могут выполняться параллельно, в противном
случае могут и т.д. Описание алгоритма преобразования схемы последовательного
алгоритма в параллельную схему заключается в следующем. Разобьем
последовательный алгоритм на N линейных участков, к=1,…,N, исключив при этом
операторы ввода-вывода информации. Терминаторы начала и конца программы
исключаются в процессе работы алгоритма. Перенумеруем операторы участков,
определим номера операторов в участках в виде: при k=1 получим u1={1, 2, … , u1*},
при k=2 получим u2={1, 2, …, u2*}, и т.д. При k=N получим uN={1, 2, …, uN*}. Сущность
алгоритма заключается в том, что отыскивается зависимость последующих процессов
алгоритма от предыдущих, и если она есть, то проводится связь между процессами
(блоками алгоритма). В противном случае связь отсутствует. Связи между участками
остаются прежними, т.е. сохраняется связь между предшествующим логическим
оператором, входящим как первый оператор участка, и последующим оператором
этого участка. Считается, что созданы линейные участки алгоритма в виде
m 1
N
,...,U кон
последовательности: Uнач, U в2н ,...,U вmн ,U кон
, Исходные данные, используемые в
алгоритме 1: Mv – множество входов в алгоритм. Flag – вспомогательная переменная.
Исходный алгоритм, который подлежит распараллеливанию, представлен на
150
рисунке 5.1.2. Он состоит из трёх участков: Uнач и двух участков – Uкон. При
изображении полученного в результате работы алгоритма 5.1.1 параллельного
алгоритма, представленного на рисунке 5.1.3 опущен оператор параллельного
действия, так как он, на наш взгляд, является излишним при построении граф-схем
параллельных алгоритмов.
Алгоритм 5.1.1.
1. Вычислим k:=1, MV:= Ø – множество входов в алгоритм, Flag:=TRUE.
2. Если uk*  2, то выполнить шаг 3, иначе – шаг 13.
3. Вычислим uk = 1.
4. Вычислим v:=uk, uk:=uk+1.
5. Если uk  uk*, то выполнить шаг 6, иначе – шаг 16.
6. Если uk зависит от v, то выполнить шаг 7, иначе – шаг 11.
7. Проводим связь из блока v в блок uk.
8. Вычислим Flag:=False.
9. Вычислим v:=v-1.
10. Если v < 1, то переходим к шагу 4, иначе – шаг 6.
11. Если Flag:=TRUE, то переходим к шагу 12, иначе – шаг 9.
12. Вычислим MV:= MV  {uk} и переходим к шагу 9,
13. Если uk*=2, то переходим к шагу 14, иначе – шаг 15.
14. Вычислим MV:= MV +{1}.
15. Все ли блоки имеют выходные связи? Если – «да», то выполнить шаг 16,
иначе – шаг 17.
16. Вычислим k:=k+1 и затем выполним шаг 18.
17. Проводим связи из блоков uk в блок uk* и переходим к шагу 16.
18. Если k  N, то переходим к шагу 20, иначе – шаг 19.
19. Конец алгоритма.
20. Очередной участок является внутренним? Если – «да», то выполнить шаг 21,
иначе – шаг 34.
21. Если uk*=3, то переходим к шагу 22, иначе – шаг 23.
22. Проводим связи из блоков uk =1 в блок uk =2 и uk =2 в блок uk* =3 и переходим к
шагу 16.
23. Вычислим uk: = 2 .
24. Вычислим v:=uk, uk:=uk+1.
25. Если uk < uk*, то выполнить шаг 26, иначе – шаг 30.
26. Если uk зависит от v, то выполнить шаг 27, иначе – шаг 28.
27. Проводим связь из блока v в блок uk.
28. Вычислим v:=v-1 и затем выполним шаг 29.
29. Если v < 2, то переходим к шагу 24, иначе – шаг 26.
30. Все ли блоки имеют входные связи? Если – «да», то выполнить шаг 32,
иначе – шаг 35.
31. Проводим связи из блока uk =1 в блоки, не имеющих входных связей.
32. Все ли блоки имеют выходные связи? Если – «да», то выполнить шаг 16,
иначе – шаг 33.
33. Провести связи из блоков, не имеющих выходных связей, в блок uk*, и затем
выполним шаг 16.
34. Если uk*=2, то переходим к шагу 35, иначе – шаг 36.
35. Проводим связи из блоков uk =1 в блок uk* и переходим к шагу 16.
36. Вычислим uk: = 2.
37. Вычислим v:=uk, uk:=uk+1.
38. Если uk < uk*, то выполнить шаг 39, иначе – шаг 43.
39. Если uk зависит от v, то выполнить шаг 40, иначе – шаг 41.
151
40. Проводим связь из блока v в блок uk и переходим к шагу 41.
41. Вычислим v:=v-1.
42. Если v < 2, то переходим к шагу 37, иначе – шаг 39.
43. Все ли блоки имеют входные связи? Если – «да», то выполнить шаг 16,
иначе – шаг 44.
44. Проводим связи из блока uk =1 в блоки, не имеющих входных связей, и
переходим к шагу 16.
На рисунке 5.1.2 представлена схема последовательного алгоритма. Фигурными
скобками выделены три участка U1, U2, U3. Двойная нумерация блоков означает, что
те блоки, которые попали в состав участков, в качестве первого номера имеют номер
блока в схеме последовательно8го алгоритма. Несовпадение номеров связано с тем,
что при построении участков были исключены терминаторы начала и конца
алгоритма. Второй номер определяет порядковый номер в множестве номеров
построенных участков. В качестве разделителя участков используется как логические
операторы на два выхода, так и логические функции на два выхода. Хотя
использование логических операторов на три и более выходов не является
принципиальным для рассматриваемого метода, и приводить только к усложнению
алгоритма 5.1.1.
Рис.5.1.3. Схема модифицированного алгоритма
Полученная схема модифицированного алгоритма затем будет преобразована в
граф-схему алгоритма, построение которого приводится ниже.
Определение 5.1.5 Ориентированный граф, представляющий некоторую схему
алгоритма, не содержащую циклов, таким образом, что каждому блоку алгоритма
соответствует вершина, а связям между блоками – дуги, называется граф-схемой
алгоритма.
В общем случае
граф–схема алгоритма – это сеть. Как следует из
определения 5.1.5 циклы исключены из граф-схем. Это сделано по нескольким причинам.
Во-первых, распараллеливание осуществляется для сложных программ, где каждый блок
схемы алгоритмов – это программный модуль, в который всегда можно включить
небольшие по времени циклы и тем самым упростить составление граф-схем алгоритмов.
Во-вторых, циклы по параметру [2] не поддаются распараллеливанию и их бессмысленно
изображать в граф-схеме, а лучше включить в программный модуль. Циклы по счётчику
циклов [2] распараллеливается, как будет показано ниже, введением дополнительных
вершин в граф – схему. Для дальнейшего рассмотрения сеть можно представить в виде
совокупности свёрток и развёрток графа.
Определение 5.1.6. Свёрткой k-й вершины граф-схемы называется наличие у k-й
вершины граф-схемы n входящих дуг, где n  1 и является конечным числом.
152
Определение 5.1.7. Развёрткой k-й вершины графа называется наличие у k-й
вершины графа n выходящих дуг, где n  1 и является конечным числом.
Свёртка и развёртка граф-схемы показаны на рис. 5.1.4.
Рис.5.1.4 Свёртка и развёртка граф - схемы
Определение 5.1.8. Изолированной k-й вершиной граф-схемы называется вершина,
у которой отсутствуют входящие и выходящие дуги.
Определение 5.1.9. Элементарной свёрткой или развёрткой k-й вершины граф-схе
мы называется наличие у k-й вершины граф-схемы одной входящей или выходящей дуги
соответственно.
Вопрос о получении или передаче значений параметров для этих случаев
представляет
несомненный
интерес
при
создании
граф-схем
алгоритмов,
предназначенных для выполнения на вычислительных системах. Рассмотрим случай
свёртки k-й вершины граф-схемы. Будем полагать, что каждый вход в k-ю вершину
рассматривается, как логическая переменная [3], которая принимает значение «истина»,
если на рассматриваемый вход приходит информация, полученная на предшествующей
вершине, в заданный интервал времени. В противном случае логическая переменная
принимает значение «ложь». Интервал времени вычисляется соответствующим
способом.Учитывая, что возможны некоторые непредвиденные отклонения, не влияющие
существенно на результаты вычислений, при обработке и передаче информации с
предшествующей i-й вершины в k-ю, введём интервал времени [-t*ik, t*ik]. Таким
образом, время прихода информации с i-й вершины определится как
Tik = ti + tik + ik , ik[-t*ik, t*ik],
(5.1.3)
где ti – время выполнения программного модуля, представленного i-й вершиной, tik –
время передачи информации с i-й вершины в k-ю вершину,ik - отклонение времени
выполнения модуля, представленного i-й вершиной, и передачи информации по k-й связи
от его среднего значения.
Перенумеруем все дуги, входящие в k-ю вершиной, получим множество дуг n.
Тогда образуется множество времён { Tik}, in и свёртку в вершине k можно трактовать
как логическую функцию n переменных. В качестве примера использования данной
концепции рассмотрим две логические функции, реализованные на свёртках или
развёртках k-х вершин, которые, как будет показано далее, полностью перекрывают
возможности,
предоставляемые
соответствующими
ЕСПД
по
изображению
последовательных алгоритмов. Функция «ИСКЛЮЧАЮЩЕЕ ИЛИ» вызывает
срабатывание к-й вершины при появлении информации на k-й дуге свёртки или развёртки
и реализует наиболее быстрый проход k-ой вершины, так как отсутствует ожидание
прихода информации на другие дуги рассматриваемой свёртки или развёртки.
Кроме того, эта функция обеспечивает наиболее надёжный узел для срабатывания, так как
вероятность не прихода информации на рассматриваемую вершину, в общем случае,
минимальна. И наоборот, функция «И» реализует наиболее медленный проход k-й
вершины и наименее надёжный узел для срабатывания, так как в общем случае, должна
прийти информация на все n дуг свёртки или развёртки. Все другие логические функции
занимают промежуточное положение по надёжности и времени срабатывания.
153
Рассмотрим времена срабатывания для развёртки с k-й вершиной для функции
«ИСКЛЮЧАЮЩЕЕ ИЛИ» и функции «И». Функция «ИСКЛЮЧАЮЩЕЕ ИЛИ»
реализуется за время для случая срабатывания i-ого выхода
Tki=tki+ tki* +ki, ki[-t*ki, t*ki],
(5.1.4)
где tki – время выполнения k-ого модуля при формировании i-ого выхода, tki* - время
передачи информации, сформированной
k-й вершины, к
i - й вершине при
формировании i-ого выхода, ki
– отклонение времени
выполнения модуля,
представленного k-й вершиной, и передаче информации по i-му каналу от его среднего
значения.
Время срабатывания для функции «И» также определяются по формуле (5.1.4), так
как одновременность срабатывания всех выходов не требуется.
Время срабатывания для свёртки с k-й вершиной для функции «ИСКЛЮЧАЮЩЕЕ
ИЛИ» также определяется по формуле (5.1.4), а для функции «И» для обеспечения
одновременного прихода сигнала в k-ю вершину время составит
Tik* = max { Tik}, in,
где Tik – времена, вычисленные по формуле (5.1.3), n – число входов в k–ю развёртку.
Очевидно, что любая граф-схема алгоритма представляет собой некоторую
последовательность свёрток – развёрток, образующих композицию из логических
функций, зависящих от n переменных, где n {1,…,}, где  – максимальное количество
дуг в свёртках и развёртках. Следует отметить особую роль времени tki*, при
формировании граф-схем алгоритмов. При рассмотрении ВС с общей памятью это время,
как правило, не учитывается и методы анализа и решения таких алгоритмов значительно
проще. Учёт времени tki* порождает класс ВС с разделяемой памятью, что приводит к
усложнению методов анализа и решения таких алгоритмов. Предлагаемая читателю
работа, также построена по принципу – «от простого к сложному». В начале представлен
материал, связанный с с методами обработки информации на ВС с общей памятью, имея
дело с информационными (ИГ) и информационно-логическими (ИЛГ) граф-схемами.
Затем исследуем ВС с разделяемой памятью и изучим информационные граф-схемами с
разделяемой памятью (ИГР) и информационно-логическими граф-схемами с разделяемой
памятью (ИЛГП). В заключения коснёмся неоднородных ВС.
Рассмотрим примеры часто используемых конструкций в граф–схемах алгоритмов,
которые могут быть реализованы с помощью предлагаемых логических функций. На
развёртках могут быть реализованы все типы основных конструкций языков
программирования, используемых для создания последовательных программ.
На функции «И» k-й развёртки может быть реализован цикл по счётчику циклов.
Так, если количество дуг, исходящей из k-й вершины, ограничено по некоторым причинам
есть n, а количество повторений в цикле – F, то количество обращений k-ого блока к
нижестоящим, связанным с ним блокам определится соотношением ]F/n[, где ][ –
функция выделения целой части положительного числа, большей или равной этому числу.
Время прохождения информации по этому каналу определится по формуле
Т kim ]F / n[*Tki
(5.1.5)
Время выполнения цикла может быть уменьшено до Т kim  Tki , если увеличить
число каналов (число процессоров) до F.
Реализация функции «Исключающее ИЛИ» на два или несколько выходов может
представлять логическую функцию на два выхода (true, false), три выхода ( > 0, < 0, = 0), а
также функцию переключения на один из каналов. Кроме того, задавая ту или иную
логическую функцию, можно получить любую комбинацию передающих каналов,
154
ориентированных на использование операторов – переключателей, используемых в
различных языках программирования или для каких либо других целей.
Определение 5.1.10. Дуги, исходящие из вершин, содержащих логические блоки,
переключатели каналов или циклы, подлежащие распараллеливанию, называются
логически зависимыми.
На рисунке 5.1.5 приведена схема алгоритма, ориентированного на представление
его в виде графа-схемы. Для простоты изложения будем полагать, что развёртка содержит
до трёх логически зависимых дуг и осуществлена развёртка цикла с помощью введения
двух дополнительных вершин под номерами 5,9,10. В общем случае требуется, ввод
дополнительных вершин, согласно соотношению (5.1.3) –
]F/n[-1 или F, если
используется число процессоров, равное числу итераций в цикле.
начало
1
А:=b +c
T
2
3
F
3
4
A>10
4
6
&
6
I:=1,10
,
F:=F+5
B[i]:=B[i]+20
7
5
9
10
7
конец
8
8
конец
а)
б)
Рисунок 5.1.5. На рисунке изображена схема алгоритма (а) и соответствующая ей
граф-схема (б).
На рисунке 5.1.5б приведён фрагмент граф-схемы, соответствующий схеме
алгоритма, изображённого в соответствии с выше указанными ЕСПД. Условный
блок 3 заменён вершиной 3 с исходящими связями, образующими логическую
функцию «Исключающее ИЛИ» на два выхода. Связи, выходящие из вершины 3 в
граф-схемах будем обозначать в виде стрелок с точками в начале. Для обозначения
связей при построении матриц, описывающих граф-схемы, будет использована
комбинация символов в виде n.m, где n – номер вершины, из которой выходит дуга,
m – порядковый номер связи. Блок цикла по счётчику циклов 4 заменён логической
функцией «И» на три входа, образуя функцию (4,5) & (4,9) & (4,10). Цикл 4 на
рис.5.1.5б заканчивается свёрткой по схеме «И». Два выхода из программы 7,8
позволяют использовать результаты вычислений на процессорах, не дожидаясь
окончательного завершения одной из ветвей программы, так как они определяют
конец параллельной ветви алгоритма. Элементарные свёртки или развёртки
вершин 1,2,3,6.7 не имеют идентификатора логических функций, хотя в соответствии с
определением алгоритма при его запуске, они должны всегда срабатывать, будем
считать, что они реализуют схему «И». Дуги, образующие схему «И» в блок-схеме
изображаются в виде стрелок. Аналогично обозначаются дуги свёрток и развёрток.
Таким образом, предлагаемая граф-схема может служить удобным средством для
изображения параллельного алгоритма.
155
Для более полного представления о возможностях использования граф-схем
приведём изображения основных операторов наиболее часто используемых языков
программирования.
5
2
1
а)
3
8
7
6
4
б)
в)
P
13
9
11
10
•••
12
R
15
W
14
n
•••
T
16
m
г)
д)
Рисунок 5.1.6. На рисунке изображена фрагменты граф-схемы алгоритма
На рисунке 5.1.6а представлена вершина граф-схемы, с помощью которой
реализуется процесс в соответствии с терминологией, используемой в ЕСПД. Рисунок
5.1.6б отображает реализацию с помощью функции «Исключающее ИЛИ» логического
оператора с двумя выходами. Аналогично, рисунок 5.1.6в – реализацию с помощью
функции «Исключающее ИЛИ» логического оператора с тремя выходами. На рисунке
5.1.6г показана реализация оператора-переключателя с n выходами типа «CASE» языка
«Паскаль» [2]. Рисунок 5.1.6д отображает реализацию фрагмента программы, в которой
начало передачи информации по всем m каналам начинает передаваться одновременно.
Используется логическая функция «И»: (13,14) & (13,15) & (13,16). На этой же схеме
реализуется цикл по счётчику циклов. Время выполнения зависит от количества итераций
в цикле, количество выделенных для вычислений цикла ВМ. Время выполнения цикла,
определяется согласно формуле (5.1.4). Идентификаторы процессов в виде чисел
записываются внутри окружностей, которыми изображаются вершины графа.
Затем составляется описание процессов:
1.
2.
3.
4.
5.
6.
7.
8.
Начало алгоритма.
Вычисляется значение переменной А.
Проверяется условие А>10.
Объявляется цикл по переменной i=1, …, 10.
Вычисляется массив значений: B[i]= B[i]+20,
Вычисляется значение переменной F:=F+1.
Конец алгоритма.
Конец алгоритма.
156
Представим
в
виде
(cм. рисунки 5.1.3 и 5.1.4).
граф-схем
рассмотренные
ранее
алгоритмы
1
2
3
2
1
4
5
8
6
9
7
10
10
3
4
5
6
8
7
9
12
a)
б)
Рисунок 5.1.7. Граф-схемы алгоритмов, представленных на рисунках 5.1.3а и 5.1.4.
Рисунок 5.1.7.б наглядно показывает, что после обработки схемы алгоритма,
представленного на рисунке 5.1.3, алгоритмом 5.1.1, модули 1,2, 4 или 5 и 6 или 7 могут
выполняться параллельно. Анализируя нумерацию блоков на рисунке 5.1.7. можно
заметить, что она не совпадает. Это связано с двумя причинами. Во-первых, блоки начала
и конца алгоритма исключены, во- вторых, при нумерации вершин граф-схемы (б)
соблюдалось правило нумерации по ярусам. Это правило, и преимущество, которое даёт
его соблюдение, будет рассмотрено ниже.
5.1.2.Использование граф-схем для представления параллельных алгоритмов
Граф- схемы алгоритмов представляются с помощью выражения G = (X, P, D), X –
множество вершин, X  {1, ..., m}. Множество вершин графа X соответствует множеству
операторов параллельного алгоритма. P = {1,...,Pm} – множество весов вершин графа. Pi
может быть скалярной величиной или вектором, i  {1, ..., m}.
Если Pi - скаляр, то
рассматривается решение этой задачи на однородной ВС (вычислительная система имеет
одинаковые процессоры). Тогда, как правило, Pi – время решения i-ого программного

модуля. Если Рi – вектор, то предполагается решение этой задачи на неоднородной ВС
(вычислительная система имеет разные типы процессоров). И, тогда, если система

содержит S разнотипных процессоров, то вектор Рi = { Pi1 ,… , Pis}, где Pi1 ,… , Pis – набор
времен решения i-ой процедуры на различных типах процессоров из множества S. D –
множество дуг графов. Дуги бывают трёх типов: di  D0, dj  D2 , dk  D3. D =
D0  D2  D3. D0- множество одиночных дуг графа, соответствующих элементарным
свёрткам или развёрткам k-х вершин граф-схемы. D2 – множество логических дуг графа,
157
реализующих функции «Исключающее ИЛИ» граф-схемы, D3 – множество дуг графа,
реализующих функции «И» граф-схемы,. Обозначим D1= D0  D3.
а)
•••
n
г)
б)
в)
Рисунок 5.1.8. Типы дуг, используемых в граф-схемах алгоритмов
На рисунке 5.1.8 показаны типы дуг, используемых граф-схемах алгоритмов. Тип а)
формирует множество D0, тип б) формирует множество D3, тип в) и г) формирует
множество D2. Коплексная стрелка г) используется в тех случаях, когда один выход
функции «Исключающее ИЛИ» соединяется с несколькими вершинами граф-схемы
одновременно. Граф-схемы бывают двух типов согласно определениям 5.1.9 и 5.1.10.
Определение 5.1.9. Граф-схема, содержащая только дуги diD1,называется
информационной граф-схемой (ИГ).
Определение 5.1.10. Граф-схема, содержащая дуги djD2, реализующие функции
«Исключающее ИЛИ» или «Исключающее ИЛИ», «И», называется информационнологической граф-схемой (ИЛГ).
1
(2,5.5)
(2,1,7)
1
(1,2,3)
2
3
3
1
2
2.1
3
2.2
2
5
4
(1,5,6)
4
(1,3, ∞)
5
5
а)
4
б)
Рисунок 5.1.9. Типы граф-схем, используемых для изображения алгоритмов
а) информационная граф-схема, используемая для решения задач на неоднородных
системах; б) информационно-логическая граф-схема, используемая для решения задач на
однородных системах
Например, информационная граф-схема, представленная на рисунке 5.1.9а,
предназначена для изображения алгоритма, который будет выполняться на неоднородных
вычислительных системах, имеющих три типа ВМ. Последовательность чисел,
заключённых в круглые скобки, расположенных возле вершин граф-схемы, представляет
собой составляющие трёхмерного вектора. Принято, что первая составляющая вектора
определяет время решения соответствующего программного модуля на первом типе ВМ,
вторая – на втором типе ВМ, третья – на третьем и т. д. Символ «  » обозначает, что
данный программный модуль не может выполняться на рассматриваемом типе
вычислительного модуля. Информационно-логическая граф-схема, представленная на
рисунке 5.1.9а, предназначена для изображения алгоритма, который будет выполняться на
однородных вычислительных системах. Вместо векторных весов используются скалярные
величины, так как будет использован одинаковый тип ВМ.
158
5.1.3. Вопросы к разделу 5.1
1 Чем дополнены схемы параллельных алгоритмов, изображённых в соответствии с ГОСТ
19.003-80 ЕСПД, ГОСТ 19.701-90 ЕСПД и рассмотренных в даном пособии?
2.Почему предложен вышерассмотренный способ разбиения последовательного
алгоритма на последовательные участки?
3. Дайте определение граф-схемы алгоритма.
4. Дайте определения свёртки и развёртки в граф-схеме алгоритма.
5. В чём разница при использовании функций «И» и «Исключающее ИЛИ» в граф-схемах
алгоритмов?
6. Можно ли использовать другие логические функции?
5.2.1. Вычисление матриц следования, расширенных матриц следования и
матриц следования с транзитивными связями
Основным инструментом анализа граф-схем алгоритмов будет служить матрица
следования [4], а также различные её модификации. Матрица следования – это
транспонированная матрица смежности [3]. Использование матрицы следования вместо
матриц смежности объясняется удобством размещения и анализа граф-схем.
Определение 5.2.1. Если в граф-схеме алгоритма существует связь между
операторами α, β и α – исполнительный блок, то в графе G существует дуга di  D1,
исходящая из вершины α и входящая в вершину β. Эту связь будем обозначать α → β и
называть информационной.
Определение 5.2.2. Если в граф-схеме алгоритма существует связь между
операторами α, β и α – логический блок, то в графе G существует дуга di  D2,
.n
исходящая из вершины α и входящая в вершину β. Эту связь будем обозначать α 
β
и называть логической или связью по управлению.
Последовательность символов над стрелкой α.n означает что дуга начинается в вершине
α и имеет номер n.
.n
 , которые непосредственно присутствуют в граф-схеме,
Связи α → β,  
назовём задающими связями. Связь «  » есть обобщённое обозначение для логической
или информационной связи.
Определение 5.2.3. Путями в графе G назовём последовательности вершин α1, …, αn,
такие, что для любой пары вершин αi, αi+1 существует дуга uD1  D2, исходящая из
вершины αi и входящая в вершину αi+5.
В виду того, что в графе G, по определению, нет циклов, то все пути имеют
конечную длину. Кроме того, будем считать, что значения логических переменных,
используемых при решении задач, не связаны друг с другом, поэтому в процессе
реализации алгоритма возможен любой из допустимых путей.
Определение 5.2.4. Характеристикой пути в графе G назовем количество вершин,
входящих в этот путь.
Определение 5.2.5. Длиной пути в графе G со скалярными весами вершин назовем
сумму весов вершин, составляющих этот путь.
Определение 5.2.6. Путь максимальной длины в графе G со скалярными весами
вершин назовем критическим и обозначим Ткр.
Примечание: в одном графе может быть несколько критических путей.
Для представления о способе построения различных матриц следования возьмём
граф-схемы рисунка 5.2.1, припишем каждой вершине некоторые произвольные
трёхмерные векторные веса. Результат представлен на рисунке 5.2.2. Важно отметить, что
матрицы следования для этих граф-схем будут отличаться, хотя вначале эти граф-схемы
были получены из одного алгоритма.
159
1
(3,2,3)
(3,2,3)
1
2
2
(1,3,3)
(1,3,3)
(2,2,1)
3
3.1
7
(4,2,1)
3.1 3 3.2
(1,1,1)
(3,∞,1)
(1,1,1)
4
3.2
4
6
(2,1,2)
(3,∞,1)
5
(1,2,1)
9
5
(2,2,1)
(2,1,2)
6
8
7
(4,5,6)
(1,2,1)
(4,5,6)
8
9
а)
б)
Рисунок 5.2.1. Граф-схемы алгоритмов, представленных на рисунках 5.5.2 а)
и 5.5.3 – б). Граф-схемы алгоритмов предназначены для использования в
неоднородных вычислительных системах
Нумерация блоков в граф-схемах рисунка 5.2.1 дана в соответствии с ярусностью.
Это даёт некоторые преимущества при изображении матриц следования. Введем в графсхему понятие яруса. Возьмем произвольную вершину α в некоторой граф-схеме G.
Найдем все характеристики путей, ведущих в α. Среди этих характеристик найдем
максимальную. Пусть это будет число h.
Определение 5.2.7. Если hα = hβ = h, то вершины α и β принадлежат одному
ярусу h. Для обеспечения получения треугольной матрицы следования для графа G
необходимо при нумерации вершин придерживаться следующего правила: вершины,
принадлежащие (h+1) ярусу, должны иметь номера большие, чем номера вершин h-ого
яруса. Внутри одного яруса вершины могут нумеровать произвольно. Такую нумерацию
назовем нумерацией по ярусам.
Теорема 5.2.1. Матрица следования получится треугольной, если в граф-схеме G
произведена нумерация по ярусам.
Предположим, что в некоторой строке δ матрицы следования существует
ненулевой элемент правее главной диагонали. Это значит, что существует связь δ+v  δ.
Т.к. номер δ+v>δ, то hδ ≤ hδ+v по условию построения матрицы S. Однако, любой путь в
вершину δ+v может быть продолжен в вершину δ, поэтому hδ > hδ+v, что противоречит
предыдущему неравенству. Элемент v был выбран произвольно, следовательно,
утверждение теоремы справедливо для любого элемента, лежащего левее главной
диагонали.
В качестве формального средства обработки граф-cхем будем использовать
матрицу следования. Для удобства изложения материала ей присвоим постоянный
идентификатор – Si i  {1, 2. …, n}. Более точное определение матрицы следования
заключается в следующем: матрица S – квадратная – количество строк и столбцов
совпадает с количеством вершин граф-cхемы. В матрица S i – ой вершине графа G
160
ставятся в соответствие i – ые столбец и строка этой матрицы. Eсли существует связь по
j .n
управлению: j 
i , то элемент матрицы равен (i,j) = j.n, при j → i образуется (i,j) = 1.
Остальные элементы матрицы S равны 0.
Для заданной матрицы Si размера m отражения весов вершин вводится понятие
расширенной матрицы следования SRi: прибавляется дополнительно k столбцов с
номерами m+1, …, m+k, где k – размерность вектора весов вершин граф – схемы.
Построим расширенные матрицы следования для граф – схем, изображенных на рис. 5.2.1.
1
2 1
3
1
4
3.1
5
3.2
6
7
8
9
1 2 3
1
1
1
1
4 5 6 7 8 9
3
1
4
1
3
2
2
4
1
S1
2
3
2
1
∞
1
2
5
2
3
3
1
1
1
2
1
6
1
1
2
3 1 1
4
3.1
5
3.1
6
3.2
7
3.2
8
9
1 2 3
1
1
4 5 6 7 8 9
3
1
4
1
3
2
2
4
1
2
3
2
1
∞
1
2
5
2
3
3
1
1
1
2
1
6
1
S2
SR1
а)
SR2
б)
Рисунок 5.2.2. Матрицы следования S1 и S2, расширенные матрицы следования SR1 и
SR2 для граф-схем алгоритмов, представленных на рисунках 5.5.2 – а) и 5.5.3 – б).
Как видим из рисунка 5.2.2. матрицы следования получаются треугольные. По
условию граф – схемы не должны содержать циклы (контуры). Это означает, что главная
диагональ всегда должна содержать нулевые элементы.
При решении задачи распараллеливания важную роль играют не только задающие
связи, но и так называемые транзитивные.
Определение 5.2.8. Если α  β, а β  γ связаны задающими связями, то
существует транзитивная связь α ⇏ γ, где «⇏» – символ транзитивной связи.
Определение 5.2.9. Множество связей, которые введены направленно внутри всех
пар элементов, принадлежащих одному пути в графе G и не связанных задающими
связями, назовём множеством транзитивных связей для заданного пути.
Определение 5.2.10. Множество транзитивных связей графа G есть объединение
множеств транзитивных связей по всем путям графа G.
Множество транзитивных связей, очевидно, полностью определяется множеством
задающих связей. При формировании множества транзитивных связей следует учитывать,
что если α  β и γμ  α, где и γμ  {γμ} – множество всех операторов, связанных с
оператором α, то все операторы {γμ} связаны транзитивно с оператором β.
Рассмотрим построение матрицы следования с транзитивными связями.
Идентификатором матрицы следования с транзитивными связями является
STi i  {1, 2. … ,n}.
Возьмем 3 произвольные вершины i, j, k такие, что между ними определены
следующие связи: связь вершины i с вершиной j, вершины j с вершиной k, вершины i с
вершиной k (рисунок 5.2.3).
161
i
Bij
j
Bik
Bjk
k
Рисунок 5.2.3. Рассматриваемая часть информационно-логического графа.
В матрице следования (рис. 5.2.4) многоточием обозначены другие связи, которые
для данного случая не представляют интереса. Напомним, что при построении матрицы Si
элементы матрицы, соответствующие логическим связям, выписываются по формуле
(5.2.1), по формуле (5.2.2) для информационных связей , отсутствие связей – по формуле
(5.2.3):
Bij=i.n,
(5.2.1)
Bij= 1
(5.2.2)
Bij= 0
(5.2.3)
…
j
…
k
…
…
…
…
…
…
…
i
…
Bji
…
Bki
…
…
…
…
…
…
…
j
…
…
…
Bkj
…
…
…
…
…
…
…
Рисунок 5.2.4. Матрица следования для фрагмента графа. Многоточием обозначены
другие связи, которые в данном случае не представляют интереса.
Таблица 5.2.1
Bij
0
0
0
1
1
L1
Bjk
0
1
L
1
L
L2
Bik = BijBjk
0
0
0
1
L
L1_ L2
Теперь необходимо произвести анализ значений типов связей между этими
вершинами и определить, какую связь между вершинами i и k выбрать: непосредственную
или через вершину j. Первое, что влияет на этот выбор - это наличие транзитивной связи
из вершины i в вершину k через вершину j. Обозначим эту связь BT. Для существования
такой связи, как было замечено выше, необходимо, чтобы обе связи Bij и Bjk были отличны
от нуля. Для проверки этой связи введем операцию «», которая аналогична операции
конъюнкции в булевой алгебре. Таблица истинности операции «» применительно к
информационно-логическим графам представлена в таблице 2. Здесь L1, L2, L обозначают
некоторые кортежи из логических связей B, где B либо некоторая логическая связь из
вершины  в вершину , либо ранее вычисленная транзитивная связь. Символ “_” –
оператор конкатенации [5]. В дальнейшем, если это не вызывает разночтений, символ “_”
с целью экономии места в ячейках матрицы заменён на «,».
162
Как нетрудно убедиться операция «» коммутативна, поэтому в таблице
приведены значения без учета перестановки операндов.
Рассмотрим построение этой таблицы более подробно. Очевидно, что транзитивная
связь есть, если обе связи Bij и Bjk отличны от нуля. Соответственно результат операции на
наборах, где хотя бы одна из связей Bij или Bjk равна нулю, будет нулевым, т.е.
транзитивная связь отсутствует. Далее, в связи с тем, что ход решения алгоритма
отражается последовательностью выполненных логических операторов, то в ситуации,
когда один операнд равен единице, а второй содержит логический тип связи, необходимо,
чтобы результат операции отражал логическую связь. Поэтому на наборе значений
операндов (1,L) результатом выполнения операции «» будет L. Исходя из тех же
рассуждений, можно сказать, что в случае, когда обе связи содержат логический тип связи
необходимо их объединить, и результатом операции на наборе (L1, L2) будет выражение
L1_ L2. Таким образом, данная операция сохраняет все логические связи, присутствующие
в пути, который начинается в начальных вершинах ИЛГ. Эта операция и позволяет
построить введённую выше транзитивную связь BT=BijBjk.
Следующим шагом будет определение, какая связь нам более важна:
непосредственная из вершины i в k – Bik или новая, вычисленная BT. Первое, на что
следует обратить внимание, как уже говорилось, это на типы связей. Более важной связью
будем по-прежнему считать логическую связь. Такой выбор делается из тех же
соображений, что и раньше.Второе, что определяет результат операции – это
непосредственно наличие хотя бы одной из связей между вершинами i и k: транзитивной
или задающей. Т.е. необходимо выбрать ненулевую связь, если она есть, при нулевом
значении другой связи. Обозначим операцию, осуществляющую такой выбор, «». Из
изложенного выше можно сказать, что ее характер подобен операции «ИЛИ» булевой
алгебры. Приведем таблицу истинности для операции «» применительно к
информационно-логическим графам, обозначив ранее вычисленную связь Bij Bik как BT.
Таким образом, для трех рассматриваемых вершин можно определить новую связь,
используя две введенные операции, т.е. связь Sik можно вычислить по следующей
формуле:
Bik=Bik(BijBjk)
(5.2.4)
или применительно к матрице следования :
(k,i)=(k,i)  ((j,i) (k,j))
(5.2.5)
После последовательного преобразования всей S мы получим матрицу ST.
Таблица 5.2.2
Bik
0
0
0
1
1
L1
BТ
0
1
L
L
1
L2
Bik  BТ
0
1
L
L
1
L1_ L2
Теперь необходимо привести алгоритм, осуществляющий такой перебор S для ее
преобразования в ST. Отправной точкой для разработки такого алгоритма является
принцип, иллюстрируемый рисунком (5.2.3). Если при просмотре некоторой строки
матрицы следования, определяющей все входящие в данную вершину связи,
обнаруживается в некотором j-том столбце ненулевой элемент, то, как показано на
163
рисунке, определяется некоторая вершина j, из которой исходит связь в вершину k. Далее
необходимо проверить все входящие в вершину j связи, т.е. проверить все вершины i, а
затем к каждой такой тройке применить формулу (5.2.5).
Используя соотношения (5.2.5) построим алгоритм, осуществляющий преобразование
матрицы S в матрицу ST.
При описании алгоритма были использованы следующие обозначения:
RS – размер матрицы следования;
(i,j) – идентификация элемента матрицы S. Первый индекс определяет строку,
второй – столбец этой матрицы. Рассматривается треугольная матрица следования,
поэтому переменные циклов, определяющих требуемые строки, изменяются: i – от
одного до RS; столбцы: j – от одного до i.
Алгоритм построения матрицы следования с транзитивными связями для
информационно-логической граф-схемы.
Алгоритм 5.2.1
В матрице следования S размера RS просматриваются строки, начиная с первой.
Если в очередной i-й строке отыскивается элемент (i,j) <>0, то вычисляются
значения
элементов
матрицы
(i,1),…,(i,j-1),
используя
соотношение,
аналогичное (5.2.5)
(i,k):= ((j,k) (i,j))  (i,k)
для k= 1,…,j-1.
3. j:=j+1. Если j <= RS, то переход на шаг 2, иначе – работа алгоритма заканчивается
(просмотрены все строки).
1.
2.
Рассмотрим пример построения матрицы следования с транзитивными связями,
используя алгоритм 5.2.1, для матрицы сдедования, представленной на рисунке 5.2.4.
При i=1 все элементы матрицы равны нулю. При i=2 все элементы матрицы
равны нулю. При i=3 элементы матрицы (3,1) равен единице, но так как согласно
условию пункта 2 алгоритма 2 в результате вычислений получается к=0, что не
удовлетворяет условию пункта 2 алгоритма.
Для четвертой вершины (i=4):
(4,1):=((2.1)  (4.2))  (4.1) = (0  1)  0 = 0
Для пятой вершины (i=5):
(5,1):=((4.1)  (5.4))  (5.1) = (0  4.1)  1 = 1
(5,2):=((4.2)  (5.4))  (5.2) = (1  4.1)  0 =4.1
(5,3):=((4,3)  (5.4))  (5,3) = (0  4.1)  0 =0
Для седьмой вершины (i=7):
(7,1) :=((5,1)  (7,5))  (7,1) = (1  (5.1)  0 = 5.1
(7,2) :=((5,2)  (7,5))  (7,2) = (4.1  (5.1)  0 = 4.1,5.1
(7,3) :=((5,3)  (7,5))  (7,3) = (0  (5.1)  0 = 0
(7,4) :=((5,4)  (7,5)) (7,4) = (4.1  (5.1)  0 = 4.1,5.1
Для восьмой вершины (i=8):
(8,1):= ((5,1  8,5))  (8,1) = (1  5.2)  0 = 5.2
(8,2):= ((5,2  8,5))  (8,2) = (4.1  5.2)  0 = 4.1,5.2
(8,3):= ((5,3  8,5))  (8,3) = (0  5.2)  0 = 0
(8,4):= ((5,4  8,5))  (8,4) = (4.1  5.2)  0 = 4.1,5.2
(8,2):= ((5,2  8,5))  (8,2) = (4.1  5.2)  0 = 4.1,5.2
В результате получим матрицу следования с транзитивными связями (таблица 5.2.4).
164
Таблица 5.2.3
2
1
1
2
3
4
5
6
7
8
4
3
5
7
6
1
0
0
1
0
1
0
0
0
2
0
0
0
1
0
0
0
0
3
0
0
0
0
0
0
0
0
4
0
0
0
0
4.1
4.2
0
0
5
0
0
0
0
0
0
5.1
5.2
6
0
0
0
0
0
0
0
0
7
0
0
0
0
0
0
0
0
8
0
0
0
0
0
0
0
0
8
Рисунок 5.2.4. Пример графсхемы с логическими связями и соответствующей ей матрицы
следования (таблица 5.2.3)
Таблица 5.2.4
1
2
3
4
5
6
7
8
1
0
0
1
0
1
0
5.1
5.2
2
0
0
0
1
4.1
4.2
4.1,5.1
4.1,5.2
3
0
0
0
0
0
0
0
0
4
0
0
0
0
4.1
4.2
4.1,5.1
4.1,5.2
5
0
0
0
0
0
0
5.1
5.2
6
0
0
0
0
0
0
0
0
7
0
0
0
0
0
0
0
0
8
0
0
0
0
0
0
0
0
Введение операций «» и «» позволяет построить матрицу следования с
транзитивными связями, в которой сохраняется информация о проходимых в процессе
выполнения алгоритма логических операторах, что позволяет исключить из программы
большое число промежуточных поисковых операций. Также устанавливается зависимость
между дугами, связанными косвенно друг с другом. Полученные в этой матрице кортежи
из логических связей могут применяться для получения вероятностей прохождения по тем
или иным путям в граф–схеме алгоритма, которые могут затем использованы при
построении эффективных планов параллельных вычислений. Кроме того, такие матрицы
могут быть использованы, например, при определении внешних и внутренних замыканий
в граф-схеме, которые будут рассмотрены позже.
На практике часто используется информационный граф, для которого
формула (5.2.5) несколько упрощается. Содержимое таблиц 5.2.1 и 5.2.2 представляются в
виде обычных функций дизъюнкции и конъюнкции, показанных в таблицах 5.2.1 и 5.2.2.
Таблица 5.2.1
Bij
0
0
1
1
Bjk
0
1
1
0
Bik = BijBjk или Bik = Bij ×Bjk
0
0
1
0
Тогда правило (5.2.5) получения матрицы с транзитивными связями существенно
упрощается и приводится к виду
(i,k):= (j,k) +(i,k)
(5.2.6)
165
Таблица 5.2.6
Bij
Bik
0
0
1
1
0
1
1
0
Bik =Bij  Bjk или Bik =Bij + Bjk
0
1
1
1
Алгоритм построения матрицы следования с транзитивными связями для
информационного графа.
Алгоритм 5.2.2.
1. В матрице следования S размера RS просматриваются строки, начиная с
первой.
2. Если в очередной i-й строке отыскивается элемент (i,j) =1, то вычисляются
значения элементов матрицы, используя соотношение, аналогичное (5.2.6)
(i,k):= (j,k) + (i,k)
для k= 1,…,RS.
3. i:=i+1. Если i <= RS, то переход на шаг 2, иначе – работа алгоритма
заканчивается (просмотрены все строки).
Рассмотрим пример построения матрицы следования с транзитивными связями для
информационного графа, представленного на рисунке 5.2.5. Приведены соответствующие
матрицы следования с задающими связями (таблица 5.2.7) и матрица следования с
транзитивными связями (таблица 5.2.8).
При нумерации вершин граф-схемы,
изображённой на рисунке 5.2.5, соблюдалось правило ярусности, поэтому в таблице 5.2.8
представлена треугольная матрица следования с транзитивными связями.
Таблица 5.2.7
2
1
4
6
5
3
7
1
2
3
4
5
6
7
8
1
0
0
1
0
1
0
0
0
2
0
0
0
1
0
0
0
0
3
0
0
0
0
0
0
0
0
4
0
0
0
0
1
1
0
0
5
0
0
0
0
0
0
1
1
6
0
0
0
0
0
0
0
0
7
0
0
0
0
0
0
0
0
8
0
0
0
0
0
0
0
0
8
Рисунок 5.2.5. Информационная граф-схема и её матрица следования, представленная в
таблице 5.2.7
Как было сказано выше, граф-схемы не должны иметь контуров, поэтому
представляет интерес алгоритм определения контуров в граф-схеме алгоритма,
позволяющий отсеять графы, не позволяющие представлять их в виде граф-схем.
Алгоритм использует свойство появления ненулевого элемента в главной диагонали
матрицы ST, если граф имеет контуры, используя следующий алгоритм. В качестве
исходной берется нетреугольная матрица S. Для получения транзитивных связей,
нижеприведенный алгоритм вызывается несколько раз до получения неизменяемой
матрицы ST или получения единицы (единиц) на главной диагонали.
166
Таблица 5.2.8
1
2
3
4
5
6
7
8
1
0
0
1
0
1
0
1
1
2
0
0
0
1
1
1
1
1
3
0
0
0
0
0
0
0
0
4
0
0
0
0
1
1
0
1
5
0
0
0
0
0
0
1
1
6
0
0
0
0
0
0
0
0
7
0
0
0
0
0
0
0
0
8
0
0
0
0
0
0
0
0
Алгоритм определения контуров в граф-схеме алгоритма.
Алгоритм 5.2.3.
1. Вычисление матрицы STi:=S, i:=0.
2. С помощью алгоритма 5.2.2, используя матрицу STi вычислить матрицу STi+1;
3. На главной диагонали матрицы STi+1 определяется: есть ли ненулевые
элементы? Если есть, то исследуемый граф имеет цикл. Если STi+1 = STi , то
исследуемый граф не имеет контуров. Конец алгоритма. Иначе определяем
STi:=STi+1 , i:=i+1 и переходим к шагу 2.
Таблица 5.2.9
1
1
2
3
2
1
3
1
1
4
1
5
1
6
1
7
4
5
1
6
1
2
3
4
5
6
7
7
Рисунок 5.2.6. Граф-схема, содержащая цикл (3, 6, 7, 3). В таблице 5.2.9 приведена
соответствующая ей нетреугольная матрица S.
После обработки матрицы S ( таблица 5.2.9 ), обнаруживающей цикл в граф-схеме,
в соответствующей матрице ST на диагонали (в ячейках (6,6) и (7,7)) появились единицы.
Таблица 5.2.10
1
2
1
3
1
4
1
5
1
6
7
1
1
1
1
1
1
1
1
1
1
1
1
1
6
7
1
1
2
3
4
5
167
5.2.2. Вопросы к разделу 5.2
1. Дайте определение транзитивным связям.
2. С какой целью можно использовать транзитивные связи?
3. Объясните разницу между длиной пути и характеристикой пути в граф-схеме
алгоритма.
4. Может ли одна транзитивная связь порождать множество транзитивных связей?
5. Какой основной критерий использовался при построении таблицы истинности для
функции «транзитивной конъюнкции»?
6. Объясните получение формулы 5.2.6 из формулы 5.2.5.
7. Определите таблицы истинности для операций «транзитивная дизъюнкция» и
«транзитивная конъюнкция».
8. С какой целью были введены эти операции?
9. Почему вычисление информационной матрицы следования значительно облегчается по
сравнению с вычислением информационно- логической матрицы следования?
10. Объясните работу алгоритма поиска контуров в граф-схеме.
5.3.1. Построение матрицы логической несовместимости.
Для реализации различных стратегий выполнения программных модулей
параллельно на ВС, важную роль играют логически несовместимые операторы, поэтому
важно создать методы, с помощью которых можно было бы манипулировать матрицами
следования, содержащими логическими операторами. Среди множества логических
операторов выделим логически несовместимые операторы.
Рассмотрим множество вершин, принадлежащих путям, начинающимся в вершине,
соответствующей i-му логическому оператору и включающей дугу 1. Это множество
назовем Mi.1. Аналогично построим множество вершин для дуги 2 – это множество
вершин, принадлежащих путям, начинающимся в вершине, соответствующей i-му
логическому оператору и включающей дугу 2 – множество Mi.2 и т.д. Для логического
оператора, содержащего n выходов, строится n путей, включающий этот логический
оператор.
Определение 5.3.1. Если операторы pj1  Mi.1, pj2  Mi.2, …, pj.n  Min , принадлежащие
различным логическим ветвям, могут выполняться в какой то из этих ветвей при
однократном выполнении алгоритма, то эти операторы называются логически
несовместимыми.
Для оценки возможности выполнения программных модулей параллельно, в
программе, содержащей логические операторы, возможно несколько вариантов
построения параллельных вычислений в зависимости от внешних факторов. Будем
считать, что при решении параллельной задачи в распоряжении пользователя имеется
количество процессоров, которое больше или равно требуемому. В этом случае можно
считать условно, что в алгоритме нет логических путей, и в ВС загружаются все
программные модули, которые возможно потребуются при решении данной программы.
Такой подход, за счёт использования дополнительного оборудования, может существенно
сократить время решения поставленной задачи. Эта же тактика может быть оправдана при
непрерывном многократном решении задачи, если исходные данные каждый раз
меняются и вероятность использования различных логических операторов достаточно
высока.
Второй способ заключается в том, что вначале, как в первом случае, загружаются все
программные модули, но затем по мере выполнения программы и прохождения
логических операторов незадействованные логические ветви отключаются, а
освободившиеся вычислительные модули поступают в распоряжение планировщика
заданий.
168
Третий способ – наиболее затратный по времени, заключается в том, что
первоначально из алгоритма исключаются все логически несовместимые операторы.
Составляется план решения усечённой задачи. Во время решения такой задачи все
исключённые ранее программные модули по мере необходимости подключаются
планировщиком заданий.
Для реализации этих трёх способов необходимо иметь методы преобразования
различных матриц, описывающих граф-схемы. Наиболее сложным, на наш взгляд,
является метод построения матриц логической несовместимости операторов.
Решение поставленной задачи заключается, в основном, в нахождении множеств
логически несовместимых операторов. Имея эти множества, можно, исключая
элементы
этих
множеств
из
множества
операторов,
представляющих
рассматриваемую граф-схему, осуществить второй или третий способы распределения
операторов по ВМ. Построение этих множеств, казалось бы, не составляет труда,
используя матрицу следования с транзитивными связями для информационнологической граф-схемы.
Для дальнейшего изложения потребуется следующие определения.
Определение 5.3.2. Пути, идущие от логического оператора и содержащего только
информационные связи за исключением первой – логической, назовём информационными
логическими ветвями.
Определение 5.3.3. Пути, идущие от логического оператора и содержащего как
логические так и информационные связи, назовём логическими ветвями.
Однако встречаются ситуации, когда информационные логические ветви i-ого
логического оператора пересекаются, т.е. Mi.1  Mi.2 ,…, Mi.n=Pi.1, …, i.n ≠ Ø. В этом случае
операторы граф-схемы pi  Pi.1, …, i.n, исключаются из множества логически несовместимых
операторов и могут планироваться для параллельного выполнения. На рисунке 5.3.1
приведена граф-схема, в которой для логического оператора один с двумя выходами на
вершине 6 произошло пересечение логических ветвей. Пересечение произошло со
стороны дуг ((1,3),(3,6)) и ((1,3),(3,5),(5,7)), связанных с дугой 1.2.
Рисунок 5.3.1. Граф-схема ИЛГ с пересечением логических путей логического
оператора 1 информационными дугами: ((1,3),(3,6)) и ((1,3),(3,5),(5,7))
Операторы 6,9 логически совместимы и могут быть запланированы для
параллельного выполнения в любом случае. Безусловно, в приведенном примере
рассматривался логический оператор на два выхода – наиболее часто используемый в
практике программирования и наиболее простой с точки зрения проводимого анализа.
Получение каких либо результатов для случая логических операторов с n выходами
при n>3 достаточно проблематично, хотя в частных случаях, в случае необходимости,
может быть получен определённый эффект. Это связано с тем, что возникает множество
комбинаций замыканий выходов логического оператора, которые должны отслеживаться
определённой программой, которая будет управлять включением-отключением
169
вычислительных модулей в процессе решения рассматриваемой задачи. Такая программа
должна тесно взаимодействовать с планировщиком заданий или входить в его состав.
1
1.1
3
2
5
4
M1T2,467
1.2
7
6
P1.1,1.2={6, 7}.
MZ1={6, 7}.
Рисунок 5.3.2.Граф-схема, имеющая замыкающие дуги и со стороны 1.1, и стороны 1.2.
Определение 5.3.4 Вершина z  Pi.1, …, i.n и имеющая наименьший номер,
называется минимальной внутренне замкнутой вершиной i-го логического оператора.
Так, для примера, представленного на рисунке 5.3.2, z =6.
Следует отметить, что замыкание логических путей может осуществляться за
счет внешних информационных связей. Как показано на рисунке 5.3.3, замыкание
может произойти за счет информационных связей, путями, идущими от операторов 3
или 4. При этом должен существовать информационный путь к вершинам 3 или 4 от
входа в алгоритм (вершина 2) или от любого из входов, если их несколько.
Анализируя ситуацию, возникающую на вершине 6, можно сделать определённые
выводы по организации решения задач с помощью граф-схем в таких ситуациях. В
данной свёртке возможны несколько вариантов прохождения этого узла:
1) Связь (4,6) срабатывает всегда, когда не приходит сигнал от связи (1,6), т.е.
реализуется схема «И» для связи (4.6) и схема «исключающее ИЛИ» для связи (1,6) и,
наоборот, срабатывает только связь (1.6) в случае появления на ней сигнала.
2) Дуги (1,6) и (4,6) реализуют схему «И» в свёртке, т.е. обеспечивается, в
случае необходимости, задержка, обеспечивающая одновременность срабатывания
сигналов. В этом случае понятие «внешнее замыкание» теряет смысл.
Выбор правил обработки сигналов определяется программистом в зависимости
от удобства программирования решаемой задачи или заранее установленных правил.
При дальнейшем изложении материала будем использовать правило 1.
M1F6,810
T1F7,8910 .
2
3
4
1.1
1.2
5
V1.1={7,9}, V1.2={6, 8, 10},
MZ1={6, 7, 8, 9, 10}.
6
7
8
9
10
Рисунок 5.3.3. Граф-схема алгоритма с замыканием логических ветвей
за счет вершин, не принадлежащих путям оператора 1
Целесообразно рассмотреть внешнее замыкание логических ветвей отдельно. Это
связано с тем, что при рассмотрении возможности параллельного выполнения операторов,
170
включенных в логические ветви, необходимо учитывать результаты внутреннего
замыкания, внешнего, имея в виду при этом, что возможно внешнее замыкание только
одной ветви.
Определение 5.3.5. Если существует информационный путь в вершину z  Mi.j от
начальной вершины граф-схемы, то вершина z называется внешне замкнутой в j-й ветви
для i-го логического оператора. Если таких вершин несколько, то вершину z с
минимальным номером называют минимальной внешне замкнутой в j-й ветви для i-го
логического оператора.
Определение 5.3.6. Если множество Mi.j={x1, …, xj, …, xj’} содержит минимальную
внешне замкнутую вершину xj, то подмножество Vi.j={ xj, …, xj’}
называется внешне
замкнутым для j-й ветви i-ого логического оператора.
При рассмотрении влияния внешних и внутренних замыканий для оценки
возможности распараллеливания операторов, принадлежащих ветвям логического
оператора, необходимо учесть, что:
1.
Внутреннее замыкание, как правило, порождает операторы, которые можно
выполнять параллельно;
2.
Для возможности распараллеливания операторов, принадлежащих путям
логического оператора достаточно одного внешнего замыкания при его
использовании.
3.
Определение множества MZi всех замкнутых операторов i-го логического
оператора требуется вычислить объединение множеств:
n
m
k 1
j 1
MZi = ( Pi.k )  (Vi. j ) ,
где Pi,k – множество внутренне замкнутых операторов i-ого логического оператора в
ветви k,
Vi,j – множество внешне замкнутых операторов i-ого логического оператора в ветви j,
n – количество внутренне замкнутых ветвей i-ого логического оператора,
m – количество внешне замкнутых ветвей i-ого логического оператора,
Ситуации, соответствующие вышеупомянутым пунктам 1, 2, проиллюстрированы на
рисунках 5.2.1, 5.2.2, 5.2.3. На рисунке 5.3.4 рассмотрена ситуация, соответствующая
пункту 3.
1
2
2.1
3
8
2,2
2 1?
4
111 5
/1
6
7
P1.1,1.2={10, 12},
V2.1 = {8, 10, 12},
MZi = {8, 10, 12}.
9
10
11
11
11
12
11
11
11
11
11
11
Рисунок 5.3.4. 11
Пример граф-схемы, в которой внешние замыкание ветвей и ветвей 2.1
и 2.2 уточняет множество операторов, подлежащих распараллеливанию
171
5.3.2. Построение матрицы логической несовместимости операторов
Матрица логической несовместимости операторов L(I,j) строится с помощью
алгоритма 5.3.1. Работа этого алгоритма основывается на поиске множества операторов,
составляющих логические ветви. Затем из логических ветвей удаляются замкнутые
вершины текущего k-ого логического оператора. Полученная матрица, составленная для
оставшихся операторов, используется в дальнейшем для построения различных способов
распределения операторов по вычислительных модулей ВС. В алгоритме рассмотрены
логические операторы на два выхода, так как они наиболее часто применяются на
практике. Увеличения количества выходов логических операторов не носят
принципиального характера, а только несколько усложняют рассматриваемый алгоритм.
Алгоритм 5.3.1. Обозначения, принятые в схеме алгоритма:
S – матрица следования; RS – размер матрицы S; ST – матрица с транзитивными связями;
RST=RS – размер матрицы ST; MLO – множество логических операторов; RMLO –
мощность множества логических операторов; M – множество вершин операторов; Mk.1 –
множество вершин операторов, принадлежащих путям, включающим дугу k.1
логического оператора; Vk.2 – множество вершин операторов, внешне замкнутых для
k ого логического оператора связи k.2; K=1, …, RMLO ; Mk.2 –множество вершин
операторов, принадлежащих путям, включающим дугу k.2 логического оператора; RMk.1
– мощность множества логических операторов ветви k.1;
RMk.2 – мощность множества логических операторов ветви k.2; Pk.1,k.2 – множество
вершин операторов, внутренне замкнутых для k-ого логического оператора;
Vk.1 – множество вершин операторов, внешне замкнутых для k-ого логического
оператора связи k.1;
MZk – объединенное множество внешних и внутренних замыканий для k-го логического
оператора;
Рассмотрим более подробно процедуры, входящие в алгоритм построения матрицы
логической несовместимости.
Процедура PMLO, получение множества логических операторов.
Признаком логического оператора матрицы S является появление в соответствующем
столбце значений j.1 или j.2, поэтому принцип работы этого алгоритма заключается в
том, чтобы найти столбец, содержащий одно из этих значений, и записать этот номер в
соответствующее множество.
Алгоритм 5.3.1.
1. В матрице S, размера RS берём первый столбец (j:=1), RMLO:=0, MLO:=Ø.
2. Просматриваем j-й столбец по строкам и определяем равенство текущего
элемента матрицы j.1 или j.2.
3. Если найден такой элемент, то полагаем MLO:= MLO  { j}; RMLO:= RMLO+1.
4. Вычислить j:=j+1.
5. Если j  RS, то перейти к шагу 2, иначе - конец алгоритма.
Процедура PMTF. Получение множества Mk.1 и Mk.2 k-го логического оператора.
Для получения множеств Mk.1 и Mk.2 k-го логического оператора необходимо
просмотреть k-й столбец матрицы ST и включить в множество Mk.1 номера операторов,
которые в соответствующих строках имеют значение k.1, и в множество Mk.2 номера
операторов, которые в соответствующих строках имеют значение k.2.
172
Начало
S, ST, RS
Обнуление матрицы
логической
несовместимости
L=0
Процедура определения
множества логических
операторов
PMLO(S, RS,
MLO, RMLO)
K=1, …, RMLO
А
Б
Mk.1,k.2(ST, RST,
MLO, Mk.1, Mk.2,
RMk.1, RMk.2)
Процедура определения
множеств Mk.1 и Mk.2 теку
щего логического оператора
Pk.1,k.2= Mk.1  Mk.2
Определение внутренних
замыканий текущего логического оператора (ТЛО)
PREZ (ST, RST,
Mk.1, Mk.2, RMk.1,
RMk.2, Vk.1, Vk.2 )
Процедура определения
внешних замыканий для
ТЛО
Получения общего количества внешних и внутренних
замыканий ТЛО
Получение незамкнутых
операторов в ТЛО
Mk= Pk.1,k.2  Vk.1  Vk.2 )
Mk.1= Mk.1\ Mk
Mk.2= Mk.2\ Mk
Б
i=1, …, RS
j=1, …, RS
L
А
Да
i  Mk.1
j  Mk.2
Нет
Конец
L(i, j):=1
L(j, i):=1
Рисунок 5.3.5. Схема алгоритма построения матрицы логической несовместимости
операторов.
173
Алгоритм 5.3.2.
1.Выбираем очередной элемент множества MLO.
2.Полагаем i:=1 (номер строки), n:=1 (номер позиции в множестве Mk.1), m:=1
(номер позиции в множестве Mk.2);
3.В соответствии с выбранным значением k, в k-м столбце матрицы ST
просматриваем i-ю строку.
4.Если элемент матрицы ST(i,k) = k.1, то Mk.1[n]:=k, n:=n+1 и переход на шаг 7;
5.Если элемент матрицы ST(i,k) = k.2, то Mk.2[m]:=k, m:=m+1 и переход на шаг 7;
6. Если условия пунктов 3, 4 не выполняются, то переход шаг 7;
7.Вычислить i:=i+1; если i  RST, то переходим на шаг 3, иначе вычислить RMT:=n,
RMF:=m, и – конец алгоритма.
Процедура PREZ. Процедура PREZ формирует множество внешних замыканий для
рассматриваемого логического оператора, используя свойства матрицы ST. Берётся i-ая
строка матрицы ST, содержащая все нули (вход ИЛГ). Затем – для i-ого столбца номера
всех элементов, равных 1, фиксируются в множестве ED. Если для рассматриваемого kого логического оператора пересечения множеств ED  Mk.1 и (или) ED  Mk.2 не пусты,
то обнаружены внешние замыкания для ветвей k-ого логического оператора (эти
пересечения и составляют номера внешне замкнутых операндов).
Алгоритм 5.3.3.
1 .Вычислим матрицу ST’, используя матрицу ST, заменив в ней связи k.1, k.2 на
нули. Примечание: записи, состоящие из последовательности нулей или конкатенации
нулей с последовательностью символов n.1 или n.2, где n – целые числа, определяющие
номера других логических операторов, преобразуются в матрице ST’ в нули.
2. Формируем множество из номеров нулевых строк матрицы ST’: ZS := {i1, ..., iq}.
Полагаем Vk.1:= Ø, Vk.2 := Ø.
3. Для всех элементов ip  ZS строим множество EDp номеров строк, содержащих
единичные элементы в ip столбцах.
4. Исключим из множеств EDp , p = 1, …, q элементы, равные номеру
рассматриваемого логического оператора k. Перенумеруем множества EDp,
учитывая удаленные элементы. Получим множества EDu, u:=1,…,f , f<q. Если все
EDu=Ø, то Vk.1:= Ø, Vk.2 := Ø.
5..Вычислить множества Vk.1 := Vk.1  (Mk.1 ∩ EDu), Vk.2 := Vk.2  (Mk.2 ∩ EDu),
u = 1,…,f, где Mk.1 и Mk.2 – множества операторов для текущего логическог
оператора. Конец алгоритма.
5.3.3. Вопросы к разделу 5.3
1. Дайте определение транзитивным логически несовместимым операторам.
2. В чём отличие между информационными логическими и логическими ветвями?
3. Дайте определение внутреннего замыкания в логическом операторе.
4. Дайте определение внешнего замыкания в логическом операторе.
5. Какая формула обеспечивает учёт всех замыканий в рассматриваемом логическом
операторе?
6. С какой целью вычисляется матрица логической несовместимости операторов?
7. Каким образом учитываются замыкания вложенных логических операторов?
174
5.4.1. Построение множеств взаимно независимых операторов.
Для определения возможности распараллеливания операторов необходимо произвести
анализ независимости операторов по данным и по управлению. Для этих целей вводится
матрица независимости операторов М.
Определение 5.4.1.
Симметричная матрица M(i, j) называется матрицей
независимости операторов, если M(i, j)=ST’(i, j) + L(i, j), где «+» – операция дизъюнкции
булевой алгебры над соответствующими элементами строк матриц. ST’(i, j) = 0, если
ST(i, j) = 0, и ST’(i, j) = 1, если ST(i, j) ≠ 0, для i = 1, .., RST и j = 1, .., RST, а L(i, j) –
матрица логической несовместимости.
Примечания. 1. Здесь матрица ST – нетреугольная, и получается из треугольной
зеркальным отображением относительно главной диагонали. 2. Для информационного
графа матрица М совпадает с матрицей ST.
Определение 5.4.2. Операторы  и  - взаимно независимые (ВНО), если в матрице
независимости М(  ,  ) = М(  ,  ) = 0 M()0.
Определение 5.4.3. Операторы { i } , i = 1, …, s, принадлежащие рассматриваемой
граф-схеме с матрицы независимости M,+ образуют полное множество ВНО, если для
любого оператора j  { i } существует пара элементов матрицы независимости
M(j)1
M(  i , j )  M ( j, i ) =1i , i = 1, …, s.
Множество ВНО, содержащее наибольшее число элементов для данного графа,
называется максимально полным.
Пусть некоторый алгоритм представлен информационно-логической граф-схемой
(см. рисунок 5.4.1.а). По нулевым элементам матрицы независимости М (см. рисунок
5.4.1.б) в строке каждого оператора можно указать множество тех операторов, каждый из
которых при выполнении некоторых условий может быть выполнен одновременно с
данным, т.е. он информационно или по управлению не зависит от данного и не является с
ним логически несовместимым.
Работа алгоритма поиска полного множество ВНО основана на использовании
стека. В стек поочерёдно заносятся строки матрицы М, а также строки, получаемые в
результате
сложения
строк
матрицы
М
по
правилу
дизъюнкции:
d
E  {( m ,1),..., (m , n)}, d  {1,..., n} , где n – размер матрицы М, а m – складываемые
 1
строки,

– символ дизъюнкции.
1
3
2
4
5
6
7
1
2
3
4
5
6
7
8
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
1
1
1
3
4
1
5
1
1
6
7 8
8
а)
б)
Рисунок 5.4.1. Граф G с информационно-логическими связями (а). Матрица
независимости М для этого графа (б). В незаполненных ячейках матрицы должны быть
вписаны нули
175
Рисунок 5.4.2. Структура стека для хранения обрабатываемых строк матрицы M
В стеке также хранится информация о том, на каком элементе закончился просмотр
строки, и какое множество ВНО при этом сформировалось. Эта информация нужна для
того, чтобы возобновить просмотр строки с того места, где была сделана остановка
(очередной виток рекурсии) и с тем же набором операторов во множестве ВНО.
Структура стека показана на рисунке 5.4.2.
Приведём алгоритм нахождения полных множеств ВНО.
Алгоритм 5.4.1.
1. Пусть W – массив полных множеств ВНО. Максимально полное множество ВНО
обозначим через A, а f – число элементов в нём. Очередное формируемое
множество ВНО обозначим через D (см. рисунок 5.4.2), d – количество элементов
в нём. Номер очередного найденного нулевого элемента в строке обозначим
через k. Изначально полагаем, что стек пуст, W:=, A:=, f:=0, D:=, d:=0,
k:=0.
2. Загружаем очередную i-ю строку в стек, i:=1, …, n, где n – размер матрицы M.
Положим D:={i}, d:=1, k:=i. Если все строки обработаны, то выполнение
алгоритма заканчивается – найдены все множества ВНО (W) и определено
максимальное – (А)
3. В строке-вершине стека находим очередной нуль, занимающий позицию j > k. Если
нуль найден, то переходим к выполнению шага 6, иначе выполняется следующий
шаг.
4.
Если такого нуля нет или все нули найдены, выполняем проверку на полноту
найденного множества D. Если в строке-вершине стека все нули соответствуют
всем операторам из D, то найденное множество полное. Производим сохранение
Wm=D и переходим к шагу 7. Если в строке-вершине есть хотя бы один нуль, не
соответствующий операторам из D, то найденное множество не является
полным. Переходим к следующему шагу.
5.
Исключаем из стека строку-вершину (не будем забывать, что, исключая
строку, мы уничтожаем и текущее значение k и D, и возвращаемся к их
предыдущим значениям) Если после этого стек исчерпан, выполняем шаг 2. В
противном случае выполняем шаг 3.
6.
В текущей вершине стека присваиваем k:=j. Складываем логически
(поэлементная дизъюнкция) часть строки (1, …, n), исключая k и d (cм. рисунок
5.2.6) из вершины стека со строкой j – формируем новую вершину стека. В новой
вершине стека формируем множество D := D  {j}, d :=d+1,
k := j . Переходим к шагу 3.
7.
Сравниваем значения d и f. Если d>f, то A:=D, f:=d. Независимо от
результата сравнения переходим к шагу 5.
Представляет интерес алгоритм нахождения операторов, входящих только в одно
множество ВНО.
Алгоритм 5.4.2.
1. Матрицу ST посматриваем сверху вниз по строкам, если просмотрены все строки,
то конец алгоритма.
176
2. В i-й строке находим множество элементов {jv}, v=1, …, k, , равных 0.
k
3. Получим дизъюнкцию строк: DSjv=  ( jv ,1),..., ( jv , RST ) .
v 1
4. Если i-я строка совпала со строкой DS j , то i-й оператор входит в 1 и только в 1
множество ВНО. Само множество ВНО определяется номерами столбцов,
имеющих нулевые значения в i-й строке.
Рассмотрим пример построения алгоритма нахождения операторов, входящих только в
одно множество ВНО, для граф-схемы, представленной на рисунке 5.4.3.
Для i=1 { j } =1, ВНО1 = 1. Для i=2 { j } ={2,3}, ВНО2 = {(2),3}. Для i=4 { j } ={4,5}, ВНО4
= {(4),5}. Для i=5,6 ВНО не существует. В множествах ВНО в круглых скобках показаны
элементы, входящие только в одно множества ВНО.
Таблица 5.4.1.
1
2
3
4
6
5
1
2
3
4
5
6
1
0
1
1
1
1
1
2
1
0
0
1
0
1
3
1
0
0
1
1
1
4
1
1
1
0
0
1
5
1
1
1
0
0
0
6
1
1
1
1
0
0
Рисунок 5.4.3. Граф-схема задачи и её матрица следования с транзитивными связями,
(таблица 5.4.1) для которой строятся множества ВНО, содержащие элементы, входящие
только в одно множество ВНО
5.4.2. Вопросы к разделу 5.4
1. Дайте определение полного множества ВНО.
2. Какие существуют два способа построения матрицы независимости операторов.
3. Для чего в стеке отведены последние две ячейки?
4. В каких случаях
осуществляется дизъюнкция очередных строк матрицы
независимости?
5. Что является критерием формирования полного множества ВНО?
6. С какой целью может быть использован алгоритм 5.4.2?
177
ГЛАВА 6. Исследование информационных граф-схем со
скалярными весами для планирования
параллельных вычислений
6.1. Численные характеристики информационных граф-схем со
скалярными весами
6.1.1 Определение ранних и поздних сроков окончания выполнения
операторов.
При исследовании граф-схем алгоритмов одними из основных характеристик
являются ранние и поздние сроки окончания выполнения операторов. Имея эти величины,
можно построить планы выполнения операторов с учётом распределения операторов по
ВМ. Необходимо подчеркнуть, что на основе граф-схемы алгоритма, можно определить:
1) Частичную упорядоченность выполнения алгоритма.
2) Веса операторов pj, j = 1, …, m (обычно – времена выполнения процедур).
3) Началом отсчёта времени решения задачи является начало выполнения
операторов, являющихся входами в алгоритм.
4) Тк – это путь максимальной длины в граф-схеме ( это минимальное время, за
которое может быть решена данная задача).
Определение 6.1.1. Ранний срок окончания выполнения оператора – это время на
нач
оси отсчёта времени, равное t1, j = t1, j  p j , j = 1 . . .m, где t1нач
, j – время начала
выполнения j-ого оператора, pj – время выполнения j-ого оператора, полученное при
минимальном времени решения задачи Т=Тк.
Определение 6.1.2. Поздний срок окончания выполнения оператора – это время на
нач
оси отсчёта времени, равное t2, j(Т) = t2 j  p j , j = 1 . . .m, где t2нач
, j – время начала
выполнения j-ого оператора, полученное при времени решения задачи Т >Тк , pj – время
выполнения j-ого оператора.
Так как величины t1, j и t2, j(Т) играют большое значение для дальнейших
исследований, поэтому рассмотрим алгоритмы вычисления ранних и поздних сроков
окончания выполнения операторов.
Алгоритм вычисления ранних сроков окончания выполнения операторов.
Алгоритм 6.1.1.
1. Вычислим t1,j: =, где j :=1,…,RS. RS – размер матрицы следования
2.
Просматриваются строки матрицы S сверху вниз, выбирается первая
необработанная строка матрицы, и осуществляется переход к следующему
шагу, если обработаны все строки, то - конец алгоритма.
3. Если выбрана j-я строка, не содержащая единичных элементов, то вычисляем t1,j:
= pj , где pj – вес j-го оператора и переходим на шаг 5.
4. Если j-я строка содержит единичные элементы, то вычисляется
t1,j: = {t1, j q } + pj,
max
где max , берётся по множеству времён t1,j q , где jq – номера элементов j-й
строки, равных единице. Если в множестве {t1, jq } есть нулевые элементы, то
выполняется шаг 6, иначе выполняется шаг 5.
178
5. Обработанная j-я строка исключается из рассмотрения. Осуществляется
переход на шаг 3.
6. Выбираем столбец j:=jq и переходим на шаг 3.
Примечание: пункт 6 алгоритма 6.1.1 используется для нетреугольной матрицы S
Алгоритм вычисления поздних сроков окончания выполнения операторов.
Алгоритм 6.1.2.
1. Вычислим t2,j: =0, где j :=1,…,RS. RS – размер матрицы следования.
2. Просматриваем столбцы матрицы S
справа налево, выбираем первый
необработанный столбец матрицы, переходим к следующему шагу. Если
обработаны все столбцы, то - конец алгоритма.
3. Пусть j – номер выбранного необработанного столбца. Если он не содержит
единичных элементов, то вычислим t2, j(Т) := T, где Т – время решения задачи,
переходим на шаг 5.
4. Если j-й столбец содержит единичные элементы, то вычисляется
t2, j(Т): =min { t2, j q (Т)-pj}, где t2, j q (Т)– поздние сроки окончания выполнения
операторов, содержащие единицы в j-м столбце. Если среди единичных элементов
содержится хотя бы один элемент, имеющий t2, j q (Т)=0, то переходим на шаг 6,
иначе выполняется шаг 5.
5. Обработанный j-й столбец исключаем из рассмотрения, затем выполняется
шаг 2.
6. Выбираем столбец j:=jq и переходим на шаг 3.
Примечание: пункт 6 алгоритма 6.1.2 используется для нетреугольной матрицы S.
Диаграммы выполнения операторов для ранних и поздних сроков – удобный способ
наглядного представления многопроцессорной обработки. Структура ИГ, при
отображении ранних или поздних сроков окончания выполнения операторов в виде
диаграмм, порождает возможные способы распределения операторов по ВМ. Каждая
строка (ветвь) диаграммы определяет множество операторов, которое целесообразно
разместить на одном ВМ. Если в диаграмме имеется n строк, то целесообразно выбрать
n ВМ для решения задачи, соответствующей данной диаграмме. Для такого способа
планирования в случае обеспечения минимального времени решения задачи
целесообразно использовать ранние сроки окончания выполнения операторов. Для
обеспечения заданного времени решения задачи Т>Ткр необходимо использовать поздние
сроки окончания выполнения операторов.
Диаграмма размещения операторов на временной оси осуществляется по правилам,
приведенным ниже.
Выполнение того или иного оператора отмечается прямоугольниками, имеющими
длину, равную весам (времени выполнения) операторов, и правую границу,
соответствующую
срокам окончания выполнения операторов. Для возможности
отображения частичной упорядоченности операторов используются совмещённые
временные оси. Прямоугольники нумеруются в соответствии с номерами вершин
исследуемого графа и между ними проводятся связи в виде стрелок, как показано на
рисунках. Рассмотрим пример построения диаграмм выполнения операторов при Т=Ткр
(см. рисунок 6.1.1а) и Т>Ткр (см. рисунок 6.1.1б). Рисунок 6.1.1а иллюстрирует ИГ, для
которого вычисляются ранние и поздние сроки окончания выполнения операторов,
рисунок 6.1.1б –матрицу следования этой граф-схемы.
Пример вычисления ранних сроков окончания выполнения операторов c помощью
алгоритма 6.1.1 для граф-схемы, представленной на рисунке 6.1.1а.
t1,1 = 1, t1,2 = 2+1=3, t1,3 =4+1=5, t1,4 =3+3=6, t1,5 =max{3, 5}+3=8, t1,6 =1+5=6,
179
t1,7 =2+6=8, =2+6=8, t1,8 = 8+8 =16.
Пример вычисления поздних сроков окончания выполнения операторов c помощью
алгоритма 6.1.2 для граф-схемы для Т=18.
t2,8 (18)=18, t2,7(18)=18, t2,6(18)=18, t2,5(18) =18-8=10, t2,4(18)=18-2=16,
t2,3(18)= min {18-1, 10-3}=7, t2,2(18)= min {16-3, 10-3}=7, t2,1(18)= min {7-4, 7-2}=3.
1
2
4
2
1
1
1
4
2
1
2
3
1
4
3
3
4
1
3
5
2
6
1
5
1
3
6
1
3
1
1
7
8
8
7
4
1
2
8
1
1
2
3
а)
4
5
8
6
7
8
б)
Рисунок 6.1.1. Пример ИГ и его матрица следования, для которого
вычислены ранние и поздние сроки окончания выполнения операторов
а)
3
2
11
1
0
2
1
2
3
2
б1
6
3
3
5
4
4
5
6
7
7
8
8
9
10 11 12 13 14 15 16
6
2
1
0
1
2
4
3
3
4
5
5
6
7
8
7
8
9
б)
10 11 12 13 14 15 16 17 18
Рисунок 6.1.2. Временные диаграммы ранних (а) и поздних (б) сроков окончания
выполнения операторов
Как следует из рисунка 6.1.2.а, эта диаграмма определяет минимальное время
решения задачи, поэтому именно ей в дальнейшем будет уделено основное внимание,
хотя в отдельных случаях может представлять интерес случай, когда Т>Ткр. В этом случае
возможно уменьшение требуемого количества ВМ. Вопрос об использовании временных
диаграмм для планирования параллельных вычислений весьма интересен. Так, строка 1
на рисунке 6.1.2.а может интерпретироваться как нить для системы параллельного
программирования Open MP и других систем программирования, у которых базовым
понятием является «нить». Далее, в разделе «Планирование параллельных вычислений
для информационных граф-схем», будет подробно рассмотрена эта проблема.
180
6.1.2. Определение функций плотности загрузки, и минимальной загрузки
для информационных граф-схем
Исследование проблемы загрузки вычислительных модулей в ВС является
достаточно сложным процессом. С одной стороны, должны быть учтены многие факторы,
связанные с функционированием ВС, с другой – с выполнением параллельной программы.
Оценим временные затраты, а также необходимое число ВМ, исходя из условия, что
время, затрачиваемое на выполнение оператора тратится ровно столько, сколько указано в
весе оператора. Зададим области определения операторов граф-схемы. Отдельный
оператор tj задан в области t1,j ≤ tj ≤ t2,j
Пусть А – множество начальных вершин, В – множество конечных вершин.
Зададим области определения интервалов времени выполнения операторов для множества
вершин графов в виде трёх неравенств.
tj ≥ pj , j  A.
(6.1.1)
tj – pj ≥ ti , если существует связь i→j , i  X\B, j  X\ A.
(6.1.2)
tj ≤ T, если j  B,
(6.1.3)
где T – время решения задач. Эта система неравенств определяет многоугольник МТ в
RS-мерном пространстве. Если точка (t1, ..., tRS)  MT, то она удовлетворяет системе
неравенств (6.1.1), (6.1.2), (6.1.3). RS – размер матрицы S.
Определение 6.1.3.
Функция
PZ ( t1, t2, …, tRS,  ) =
RS
 OP(t , ) ,
j 1

1 если   (t j  p j , t j )
OP(tj,)= 
, называетcя плотностью
0
если


(
t

p
,
t
)

j
j
j

системы для значений {t1, …, tRS} в точке .
j
где
загрузки вычислительной
В качестве примера вычисления функции PZ рассмотрим диаграмму рисунка 6.1.2.а.
Значение функции PZ(1, 3, 5, 6, 8, 6, 8, 16, ) при  =1 равно единице, при  =3 равно
двум, при  =6 равно трём.
Зафиксируем моменты окончания выполнения операторов таким образом, чтобы
точки (t1, t2, …, tRS )  MT. Значение функции PZ в каждый момент времени формируется в
том числе операторами множества ВНО, т.е. в каждый момент времени значение функции
PZ совпадает с числом одновременно выполняемых операторов.
Вычислим Q = max{ q1, …, qs}, где qi –множество ВНО, тогда можно утверждать, что
PZ ( t1, t2, …, tRS,  ),
Q = max
(6.1.4)
( t1 ,..., t RS )M T
так как возможна ситуация, когда выполняются все операторы максимально полного
множества ВНО. Учитывая соотношение (6.1.4), сформулируем лемму 6.1.1.
Лемма 6.1.1. Минимальное число N вычислительных модулей однородной ВС,
способных выполнить данный алгоритм за время Т  Ткр не превышает f, где f –
количество элементов в максимально полном множестве ВНО.
b
Определение 6.1.3. Функция Z(t1, …, tRS, a, b)=  PZ( t1, …, tRS,  ) d 
называется
a
(t1T,.RS)M
загрузкой отрезка [a, b]  [0, T] для точки (t1, …, tRS) MT.
С помощью функции Z определяется загрузка отрезка [a,b], выполняемыми на этом
отрезке операторами.
181
Определение
6.1.4.
Функция
Z(T)(a,
b)= min
( t1 ,..., tRS MT
Z (t1 ,..., tRS , a, b)
называется
(t,.)D
(t,.)M
минимальной загрузкой отрезка [a, b]  [0, T] для 1TRS точки 1TRS (t1, …, tRS)  MT.
Смысл этого определения заключается в том, что при любом планировании
операторов для выполнения при решении задачи за время Т, загрузка отрезка
[a, b]  [0, T] не может быть меньше вычисленной величины.
Для составления алгоритма вычисления данной функции введем функцию  (x) :
x при х  0
 (x) =
0 при х < 0
При выборе интервалов для определения минимальной загрузки время окончания
выполнения оператора размещается на отрезке [t1,j, t2,j], который случайным образом
ложится на рассматриваемый интервал, поэтому целесообразно различные случаи
относительного размещения интервалов [a, b]и [t1, j, t2, j]. Все возможные ситуации
представлены на рисунке 6.1.3.
t1, j-pj
a
t1, j
t2, j(T)
b
t
a t1, j-pj t2, j(T)-pj b
t2, j(T) t
б)
a)
t1, j-pj
a
t2, j(T)-pj
t1, j
b
t2, j(T)
в)
а t1, j-pj
t2, j(T)
г)
b
t
t1, j-pj t2, j(T)-pj
a
д)
b
t2, j(T) t
Рисунок 6.1.3. Относительное размещения интервалов [a, b] и [t1, j, t2, j].
На рисунке 6.1.3.а оператор при раннем сроке окончания выполнения оператора
попадает в рассматриваемый интервал частично. На рисунке 6.1.3.б оператор при позднем
сроке окончания выполнения оператора попадает в рассматриваемый интервал частично.
На рисунке 6.1.3.в оператор при раннем сроке его окончания и позднем сроке окончания
попадает в рассматриваемый интервал частично. При определении минимальной функции
загрузки необходимо выбрать его минимальную часть. На рисунке 6.1.3.г оператор
попадает в рассматриваемый интервал полностью, поэтому время выполнения оператора
включается полностью в рассматриваемый интервал. На рисунке 6.1.3.д оператор
включает рассматриваемый интервал полностью, поэтому вклад оператора в загрузку
определяется длиной рассматриваемого интервала.
Алгоритм вычисления функции минимальной загрузки отрезка Z(T)(a, b).
Алгоритм 6.1.3.
1. С помощью алгоритмов 6.1.1 и 6.1.2 вычисляются ранние t1,j и поздние t2, j(T) сроки
окончания выполнения операторов.
2. Полагаем Z(T)(a, b):=0.
3. Анализируем последовательность операторов j:=1, …,RS.
182
4. Вычислим Z(T)(a, b):= Z(T)(a, b)+min{  (t1, j  a ),  (b  t2, j (T )  p j ), pj, b-a }
5. После перебора всех операторов получаем значение Z(T)(a, b).
При разработке и эксплуатации ВС одним из основных вопросов является
определение требуемого количества ВМ для решения поставленной задачи за время Т или
при заданном количестве ВМ определить, сколько потребуется времени для решения
задачи. Ответ на этот вопрос дают две теоремы Барского [4].
Теорема 6.1.1. «Об оценке снизу числа ВМ, необходимых для решения задачи за
время Т ».
Для того чтобы N вычислительных модулей было достаточно для выполнения
заданного алгоритма за время Т необходимо, чтобы для отрезка[a, b]  [0, T]
выполнялось соотношение
Z(T)(a, b)  N(b-a)
(6.1.5)
Доказательство. Согласно лемме 6.1.1 существует неравенство
max PZ ( t1, t2, …, tRS,  )  N.
(6.1.6)
( t1 ,..., t RS )M T
Для любого отрезка времени [a, b]  [0, T]согласно определению 6.1.4 справедливо
неравенство
Z(T)(a, b)  Z(t1, …, tRS, a, b).
(6.1.7)
По определению 6.1.3:
b
Z(t1, …, tRS, a, b)=  PZ( t1, …, tRS,  ) d  .
(6.1.8)
a
Заменив, используя неравенство (6.1.6), подынтегральную функцию выражения (6.1.8)
значением N, и учитывая неравенство (6.1.6), получим выражение (6.1.5).
Отсюда
N  Z(T)(a, b)/ (b-a) .
Необходимость, но недостаточность условия теоремы 6.1.1 можно продемонстрировать
на следующем примере. Пусть задана граф-схема в виде, представленном на рисунке 6.1.4.
1 1
1 4
1 2
1 5
1 3
1 6
3
6
2
5
1
4
0
1
2
3
Рисунок 6.1.4. Иллюстрация выполнения условия необходимости и достаточности к
теореме 6.1.1.
Определим число ВМ, необходимых для решения задачи, представленной графсхемой на рисунке 6.1.4 Для этого проанализируем минимальную загрузку
интервалов [0,1], [1, 2], [2, 3], [0, 2], [1, 3] и [0, 3]:
Z(3)(0, 1)= Z(3)(1, 2)= Z(3)(2, 3)=0, Z(3)(0,2)= Z(3)(1, 3)=3, Z(3)(0, 3)=6.
Согласно теореме 6.1.1 требуется два ВМ. Разместить операторы диаграммы,
представленной на рисунке 6.1.4 на двух ВМ, не представляется возможным.
Теорема 6.1.2. «Об оценке снизу времени выполнения задачи при заданном количестве
процессоров».
Если Т1 – оценка снизу времени выполнения алгоритма, представленного
информационным графом со скалярными весами вершин на ВС, имеющей N процессоров,
и на отрезке [a, b]  [0, T] выполняется соотношение
Z (T1 ) (a, b)  N (b  a)  d  0
183
тогда наименьшее время Т реализации алгоритма удовлетворяет соотношению
Т  Т1  d / N .
Доказательство. Найдём величину g>0, такую, чтобы объём работ Z (T1 ) (a, b)
выполнялся и при значении Т=Т1+g на интервале [a, b+g], но так же выполнилось
условие (6.1.5): Z (T1  g ) (a, b  g )  N (b  g  a),
тогда Z (T ) (a, b)  Z (T1  g ) (a, b  g )  N (b  g  a)  N (b  a)  d , отсюда получим g=d/N.
Алгоритм определения оценки минимального числа процессоров, необходимого для
выполнения алгоритма за время Т, составленный на основании теоремы 6.1.1.
1
Алгоритм 6.1.4.
1. Вычислить N:=0.
2. Последовательно берутся интервалы [a, b]  [0, T] в порядке:
[0,1]
[0,2], [1,2],
[0,3], [1,3], [2,3]
…
ZT(a,b)
N1
3. Для очередного интервала [a, b] вычислим N1= Z(T)(a, b) / (b-a) (ba), где Z(T)(a, b)
определяется по алгоритму 6.1.3.
4. Если N1>N, то N:= N1.
5. После обработки всех интервалов, получается требуемое N .
[0,T], [1,T],…, [T-1,T]. Всего отрезков: Т(Т+1)/2.
Алгоритм определения оценки минимального времени Т выполнения заданного алгоритма
на ВС, содержащей N процессоров, составленный на основании теоремы 6.1.2.
Алгоритм 6.1.5.
1. Вычислим Т:=Ткр.
2. Просматриваются интервалы [a, b]  [0, T], как в алгоритме 6.1.4 пункте 2.
Примечание. При таком выборе последовательности отрезков значение T можно
увеличивать, не пересчитывая при этом ранее вычисленные значения d.
3. Для очередного интервала [a, b]вычислим значение
(T)
d:= dZ(a,b)N Z(T)(a, b)-N(b-a),
где Z(T)(a, b) определяется по алгоритму 6.1.3.
4. Если d>0 вычисляется
T:=T+]d/N[.
где ]x[ – ближайшее целое, не меньшее x.
5. Вычислим
t2, j(T):= t2, j(T)+]d/N[, j=1, …, RS
6. После обработки всех интервалов вычисляем значение Т – нижнюю оценку
минимального времени выполнения данного алгоритма на данной ВС.
6.1.3. Вопросы к разделу 6.1
1. Определите соотношения, задающие последовательность следования в граф-схеме
алгоритма.
2. В каких пределах изменяется время выполнения оператора?
3. В каких случаях может наступить равенство ранних и поздних сроков окончания
выполнения операторов?
4. На чём основано утверждение леммы 6.1.1?
5. Как связаны точки SR-мерного многоугольника МТ с точками интервала [a, b]?
6. Объясните, почему на интервале [0, 1] рисунка 6.1.3 минимальная загрузка равна 0.
184
7. Объясните, в каких ситуациях используется теорема 6.1.2.
8. Почему важен порядок следования интервалов при выполнении алгоритма 6.1.5.
9. Не является ли Ткр нижней оценкой минимального времени выполнения данного
алгоритма
10. Согласно теореме 6.1.2 всегда ли можно найти величину g, удовлетворяющую
поставленным условиям?
15.Чем вызвана необходимость коррекции поздних сроков окончания выполнения
операторов в алгоритме 6.1.5 шага 5?
12. Объясните, почему при выборе последовательности отрезков, как в алгоритме 6.1.4
пункте 2, значение T можно увеличивать, не пересчитывая при этом ранее вычисленные
поздние сроки окончания выполнения операторов?
13. Как можно дополнить алгоритм 6.1.5, если Ткр по определённым причинам нельзя
определить?
14. Чем объясняется выбор интервалов для определения минимальной загрузки вносимой
оператором, который случайным образом ложится на рассматриваемый интервал?
6.2.1. Распределение операторов по ВМ вычислительной системы с общим
полем памяти для информационной граф-схемы
Построенные диаграммы (см. рисунок 6.1.2.) является удобным средством
построения плана распределения операторов по ВМ вычислительной системы. Строки
временной диаграммы будем интерпретировать как нити алгоритма решаемой задачи, в
соответствии с установившейся терминологией. Для удобства размещения операторов
алгоритма на вычислительные модули ВС, представим структуру ВС в виде матрицы
дистанций между вычислительными модулями ВС, в которой указаны расстояния между
ВМ, измеренные в количестве ВМ между двумя рассматриваемыми. В качестве примера
возьмём обобщённый 3-х мерного гиперкуба 2х3х3, представленный на рисунке 6.2.1.
Рисунок 6.2.1. Схема представления обобщенного 3-х мерного гиперкуба 2х3х3
Построим для него матрицу дистанций, которую, в дальнейшем удобно
использовать для размещения нитей решаемой задачи. Нумерация ВМ производится, как
показано в таблице 6.2.1.
Матрица дистанций представлена в таблице 6.2.2. В последней строке приведены
итоговые суммы по столбцам. Минимальная сумма определяет лучший ВМ, который
имеет минимальное расстояние ко всем остальным ВМ. В данном случае лучшими ВМ
являются вычислительные модули с номерами 9 и 11.
185
Рассмотрим алгоритм, представленный граф-схемой на рисунке 6.2.2.
3
5
1
2
4
3
7
5
4
5 ••• 5
8
6
5
6
7
16
00
6
3
9
17
22
6
3 19
18
3 20
3 21
25
26
3
8
27
3 23
\\
4
24
7
8
5
Рисунок 6.2.2. Граф-схема примера алгоритма решаемой задачи. Вершины 7, …, 16
представляют ветви цикла. Вершина 19, …, 22 отображает так же распараллеленный цикл
Для построения нитей решаемой задачи построим диаграмму ранних сроков
окончания выполнения операторов. Используя алгоритм 6.1.1, вычислим t1,1, …, t1,27.
Вычисленные данные представлены в таблице 6.2.3. Диаграмма ранних сроков окончания
выполнения операторов представлена на рисунке 6.2.3.
Tак как рассматривается ВС с общей памятью, обмена данными через каналы связи
между процессорами нет, и количество нитей меньше, чем число процессоров, поэтому
распределение нитей между ВМ может осуществляться, например, следующим образом:
первая нить загружается в первый ВМ, вторая – во второй и т. д. Процессоры с шестого по
тринадцатый освобождаются в момент относительного времени Т=18 и могут быть
распределены для решения других задач. Аналогично процессоры 6,7,8,9,10,11,12 также
могут быть использованы другими задачами по мере их освобождения, что наглядно
видно из рисунка 6.2.3.
Таблица 6.2.1
Кордината
ВМ(х, у, z)
Номер ВМ
Кордината
ВМ(х, у, z)
Номер ВМ
000
100
010
020
110
120
001
101
011
1
021
2
111
3
121
4
002
5
102
6
012
7
022
8
112
9
122
10
11
12
13
14
15
16
17
18
Построим нити для диаграммы, представленной на рисунке 6.2.2. Первую нить
составят операторы: Н1={1, 3, 7, 18, 24}, H2={2, 8, 19, 23}, H3={9, 20, 26}, H4={10, 21, 25},
H5={11, 22, 25}, H6={12}, H6={12}, H7={13}, H8={14}, H9={15}, H10={16}, H11={4},
H12={5}, H13={6,14}.
186
Таблица 6.2.2
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
0
1
1
2
2
3
1
2
2
3
3
4
2
3
3
4
4
5
45
t1,1
t1,15
12
2
1
0
2
3
1
2
2
1
3
4
2
3
3
2
4
5
3
4
45
3
1
2
0
1
1
2
2
3
1
2
2
3
3
4
2
3
3
4
39
t1,2
5
t1,16
12
4
2
3
1
0
2
1
3
4
2
1
3
2
4
5
3
2
4
3
45
t1,3
7
t1,17
14
5
2
1
1
2
0
1
3
2
2
3
1
2
4
3
3
4
2
3
39
t1,4
11
t1,18
18
6
3
2
2
1
1
0
4
3
3
2
2
1
5
4
4
3
3
2
45
7
1
2
2
3
3
4
0
1
1
2
2
3
1
2
2
3
3
4
39
t1,5
12
t1,19
17
t1,6
14
t1,20
17
8
2
1
3
4
2
3
1
0
2
3
1
2
2
1
3
4
2
3
39
9
2
3
1
2
2
3
1
2
0
1
1
2
2
3
1
2
2
3
33
t1,7
12
t1,21
17
10
3
4
2
1
3
2
2
3
1
0
2
1
3
4
2
1
3
2
39
t1,8
12
t1,22
17
11
3
2
2
3
1
2
2
1
1
2
0
1
3
2
2
3
1
2
33
12
4
3
3
2
2
1
3
2
2
1
1
0
4
3
3
2
2
1
39
t1,9
12
t1,23
21
13
2
3
3
4
4
5
1
2
2
3
3
4
0
1
1
2
2
3
45
t1,10
12
t1,24
22
14
3
2
4
5
3
4
2
1
3
4
2
3
1
0
2
3
1
2
45
t1,11
12
t1,25
24
15
3
4
2
3
3
4
2
3
1
2
2
3
1
2
0
1
1
2
39
16
4
5
3
2
4
3
3
4
2
1
3
2
2
3
1
0
2
1
45
17
4
3
3
4
2
3
3
2
2
3
1
2
2
1
1
2
0
1
39
18
5
4
4
3
3
2
4
3
3
2
2
1
3
2
2
1
1
0
45
Таблица 6.2.3
t1,12 t1,13 t1,14
12 12 12
t1,26 t1,27
25 22
Номера вычислтельных модулей
14
13
6
12
5
11
4
17
10
16
9
15
8
14
7
13
6
12
5
11
22
27
4
10
21
25
9
20
3
2
2
1
1
0
1
8
3
2
3
4
7
5
6
7
8
26
19
18
9
24
23
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Относительное время
Рисунок 6.2.3. Диаграмма ранних сроков окончания выполнения операторов
187
Паузы, возникшие на 6, 7, 12, 13 моментах времени связаны с синхронизацией
вычислений, определяемой структурой рассматриваемой граф-схемы. Общее время
решения этой задачи составляет 28 условных единиц.
Анализируя представленный способ построения плана решения задач на ВС,
можно сделать вывод, что достаточно простыми средствами можно построить достаточно
эффективную процедуру организации решения параллельных задач на ВС.
6.2.2. Распределение операторов по ВМ вычислительной системы с общим
полем памяти для информационно-логической граф-схемы
Информационно-логическая граф-схема, как известно, отличается от
информационной наличием логических операторов, а так же операторов выбора
вариантов, поэтому здесь возможно несколько вариантов построения планов
распределения операторов по вычислительным модулям ВС. Так первый, наиболее
простой, аналогичен рассмотренному в предыдущем разделе способу. Можно
предположить, что логические операторы и операторы выбора вариантов условно
заменены обычными, вычислительными оператораторами. Схема решения такой задачи
аналогична выше рассмотренной.
Недостатком такого подхода является предварительное резервирование ВМ,
которые не все отанутся востребованными. При использовании этого метода количество
неиспользуемых ВМ может быть уменьшено за счёт учёта требований на количество ВМ
для обработки логических путей, использующих максимальное количество ВМ:
r
( L)
N max
  (max (q j ,i ) ,
j 1
i
где r – количество логических операторов в программе, qj,i – количество ВМ,
L)
необходимых для реализации i-й ветви j-ого логического оператора. N (max
– максимальное
количество ВМ, необходимых для реализации логических путей решаемой задачи. В этом
( L)
случае требуемое количество ВМ уменьшится на N* = N  N maх
.
Второй способ в построении некоторого динамического плана, состояние которого
изменяется каждый раз, как только выполняется очередной логический оператор. Такой
план в дальнейшем будем называть адаптивным. Рассмотрим построение такого плана,
используя граф-схему, представленную на рисунке 6.2.4.
Диаграмма для информационно-логической граф-схемы, представленной на рисунке
6.2.4 представляется множеством диаграмм по мере поступления логических переменных.
Предполагаемое количество ВМ, необходимых для решения этой задачи, можно оценить с
помощью формулы qj,i, где qj,i – количество ВМ, необходимых для реализации i-й ветви jого логического оператора. Если в граф-схеме, представленной на рисунке 6.2.4,
логический оператор «один» срабатывает по дуге 1.1, то очередная диаграмма будет
выглядеть, как показано на рисунке 6.2.5.
При срабатывании условного оператора «один», дуги 1.1 требуется 10 ВМ. Время
решения задачи составит 22 условные единицы.
Если же в условном операторе «один» выбирается дуга 1.2, то диаграмма
преобразуется, как показано на рисунке 6.2.6. Для реализации этой диаграммы требуется
всего пять ВМ, которое может быть уменьшено за счёт учёта работы логического
оператора «17», Наиболее нагруженная ветвь «17.3», поэтому представим временную
диаграмму для ветви «17.3. Диаграммы для остальных ветвей строятся аналогично.
188
3
1.2
5
2
1
1.1
4
6
4
59
7
6
9
3
5
5 ••• 5
8
7
6
3
16
00
6
17.1
17.2
3
18
17
519
19
3
17.4
17.3
20
22
3
21
3
8
27
26
25
24
3 23
4
7
8
5
Рисунок \\6.2.4. Информационно-логическая граф-схема, реализованная в виде
композиций логических функций «И» и «Исключающее ИЛИ»
Номера вычислтельных модулей
12
11
10
16
9
15
8
14
7
13
6
12
5
11
4
10
3
9
2
8
1
0
1
1
3
2
3
4
23
7
5
6
7
8
18
9
10
24
11 12 13 14 15 16 17 18 19 20 21 22 23 24
Относительное время
Рисунок 6.2.5. Диаграмма ранних сроков окончания выполнения операторов для
информационно-логической граф-схемы при срабатывании дуги 1.1.
Номера вычислтельных модулей
7
6
5
4
17
3
1
0
22
27
21
25
26
6
20
2
5
19
1
4
1
2
3
4
5
6
7
8
9
24
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
Относительное время
Рисунок 6.2.6. Диаграмма ранних сроков окончания выполнения операторов при
срабатывании дуги 1.2.
189
После учёта работы всех логических операторов, в зависимости от исходных
данных, определяющих ту или иную ветвь срабатывания логических операторов,
количество используемых операторов колеблется от 10 до трёх. При использовании ВС с
общей памятью распределение операторов по ВМ может быть произвольным. Например,
первую нить, образованную операторами {1, 2, 4} можно загрузить в первый процессор,
вторую, представленную множеством {5, 17, 21, 26}, выполнить на втором процессоре, и,
наконец, третью нить {6, 27} выполнить на третьем процессоре. Варианты выполнения
плана в случае использования функций «Исключающее ИЛИ» могут быть упорядочненны
в порядке убывания вероятностей. Вероятность окончания решения задачи по тому или
иному варианту может быть получена на основании заранее определённых
вероятностей Pi,j, где i – номер рассматриваемого логического оператора, j – номер выхода
в логическом операторе. Из анализа транзитивной матрицы следования информационнологической граф-схемы решаемой задачи можно определить требуемые вероятности
следующим образом. Просматривая столбцы этой матрицы, находим поледние элементы
столбца, содержащего конкатенацию символов, определяющих выходы операторов
«Исклющающее ИЛИ». Затем конкатенацию символов i(r1)v1_ i(ri)vi_…_ i(rn)vn заменяем на
произведение вероятностей – Pреш=P(r1)v1*…* P(rn)vn, где Pреш – вероятности решения
задачи при том или ином варианте исходных данных решаемой задачи, P(ri)vi – вероятность
выбора ri логическим оператором vi пути.
Номера вычислтельных модулей
6
5
4
17
3
6
2
5
1
1
4
0
1
2
3
4
5
6
27
21
7
8
9
1
0
1
1
1
2
1
3
1
4
1
5
26
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
Относительное время
Рисунок 6.2.7. Диаграмма ранних сроков окончания выполнения операторов при
срабатывании дуги 17.3.
6.2.3. Распределение операторов по ВМ вычислительной системы с
распределённой памятью для информационной граф-схемы
При построении плана распределения операторов по ВМ вычислительной системы с
распределённой памятью для информационной граф-схемы возникают определённые
трудности, связанные с передачей информации через транзитные ВМ. Предлагаемый
метод основывается на методе, изложенном в предыдущем разделе. Сущность метода
заключается в том, что на первом этапе создаются нити без учёта обмена информацией
между ВМ. Затем при построении нитей в моменты обмена данными длины нитей
корректируются на время обмена информацией ав данной точке. Вначале получаем
модифицированные веса вершин в виде pm,j=pj+qj,i ,где pj – вес j-й вершины, qj,i – вес дуги,
исходящей из j-й вершины. При использовании транзитных ВМ модифицированный вес
возрастает на qj,i(n-1), где n – количество используемых транзитных процессоров.
190
4
2
3
5
4
3
6
4
2
2
4
1
3
4
•••
3
3
5
1
2
3
610
4
3
3
12
11
2
4
13
4
9
4
1
2
14
5
15
Рисунок 6.2.8. Граф-схема примера алгоритма решаемой задачи для ВС с распределённой
памятью.
Для рассматриваемой граф-схемы определим ранние сроки окончания выполнения
операторов без учёта времён обмена информацией между операторами: t 1,1=4, t1,2=6, t1,3=9,
t1,4=5, t1,5=9, t1,6=9, t1,7=9, t1,8=9, t1,9=9, t1,10=9, t1,11=13, t1,12=16, t1,13=17, t1,14=15, t1,15=18.
Современные структуры ВС могут работать в двух режимах передачи информации.
Первый режим характерен тем, что во время выполнения обработки данных, ВМ не может
осуществлять передачу информации. Во втором режиме возможна одновременная
обработка и передача информации. Рассмотрим первый режим обработки информации.
Учёт времён передачи информации осуществляется, используя соотношения: для
развёртки – p,j=qi,j+pj, где j= m, n – номера операторов, образующих развёртку; для свёртки
– pj= qj,i +pj где j= m, n – номера операторов, образующих cвёртку. Этим соотношениям
удовлетворяют ранние сроки окончания выполнения операторов с учётом времён
передачи информации. Модифицированные веса составят: p1=4, p2=4, p3=9+2=11,
p4=4+3=7, p5=7, p6=7, p7=7, p8=7, p9=7, p10=7, p11=4, p12=6, p13=6, p14=6, p15=6. Ранние
сроки окончания выполнения составят:t1,1=4, t1,2=8, t1,3=15, t1,4=11, t1,5=15, t1,6=15, t1,7=15,
t1,8=15, t1,9=15, t1,10=15, t1,11=19, t1,12=25, t1,13=25, t1,14=25, t1,15=25.
Рисунок 6.2.9. Матрица следования с указанием весов дуг и вершин (SDR) для граф-схемы
примера алгоритма решаемой задачи для ВС с распределённой памятью
Построим матрицу следования для граф-схемы, показанной на рисунке 6.2.8. В
матрице, представленной на рисунке 6.2.9, указаны веса дуг, определяющих времена
обмена информацией между указанными операторами, а в 16-ом столбе приведены веса
191
операторов, с помощью которых определяется время выполнения программного модуля.
По вычисленным ранним срокам окончания выполнения операторов с учётом передачи
информации построим диаграммы решения поставленной задачи.
8
10
9
8
7
6
7
6
5
4
3
4
3
2
2
1
1
0
1
2
3
4 5 6
11
5
7
8
9
15
14
13
12
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Рисунок 6.2.10. Диаграмма ранних сроков окончания выполнения операторов для графсхемы 6.2.8 с учётом времён передачи информации между операторами. Передача
информации показана стрелками.
Алгоритм построения нитей для граф-схемы алгоритма решаемой задачи с учётом
времени передачи информации. ВМ может только обрабатывать или только передавать
информацию.
Алгоритм построения нитей.
Алгоритм 6.2.1.
1. Просматриваем матрицу SDR по строкам сверху вниз. Если просмотрены все строки,
то – конец алгоритма.
2. Если в i-й строке найдено одно число, то вес i-й вершины модифицируется к виду:
рi:=pi+qj,i . Если в i-й строке найдено несколько чисел, то веса вершин модифицируются
следующим образом: рj:=pj+qi,j ,j={ m, n }, где ,j – множество столбцов, в которых
найдены числа, qi,j – множество весов дуг, принадлежащих i-й строке .
3. Используя модифицированные веса, с помощью алгоритма 6.1.1 вычисляем ранние
сроки окончания выполнения операторов.
4. Вычисленные ранние сроки окончания выполнения операторов служат основой для
построения диаграммы загрузки ВМ. Каждая строка диаграммы может служить
нитью для загрузки в процессор.
Полученные нити разместим на структуре типа обобщённый гиперкуб
(см. рисунок 6.2.1), учитывая, что ветви цикла с целью обеспечения минимального
времени вычисления цикла должны иметь одинаковое время передачи данных. Находим
нить, содержащую начальную вершину граф-схемы. В матрице дистанций определяем
строки с минимальными суммами. В данном случае – это 9-я и 11-я строки. Выбираем 9-ю
строку. В 9-й строке (9-м ВМ) расположим первую нить. В таблице 6.2.4 эта ситуация
отображается символом «+.». Далее пытаемся разместить цикл, который организуется
пятым оператором первой нити. На ближайшем расстоянии к 9-й строке находятся 3-й, 7й, 10-й, 11-й и 15-й столбцы. С помощью этих ВМ можно организовать цикл. Так как
самых близких ВМ (расстояние=1) на все нити цикла не хватит, то выбираем еще 2 ВМ с
расстоянием до 9-го ВМ равным 2 (1-й и 4-й ВМ). Размещаем на главной диагонали
соответствующие нити с указанием её номера и точки. Точка используется для облегчения
визуализации нити.
192
Таблица 6.2.4
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
9.
1
1
2
2
3
1
2
2
3
3
4
2
3
3
4
4
5
45
2
1
0
2
3
1
2
2
1
3
4
2
3
3
2
4
5
3
4
45
3
1
2
3.
1
1
2
2
3
1
2
2
3
3
4
2
3
3
4
39
4
2
3
1
10.
2
1
3
4
2
1
3
2
4
5
3
2
4
3
45
5
2
1
1
2
0
1
3
2
2
3
1
2
4
3
3
4
2
3
39
6
3
2
2
1
1
0
4
3
3
2
2
1
5
4
4
3
3
2
45
7
1
2
2
3
3
4
4.
1
1
2
2
3
1
2
2
3
3
4
39
8
2
1
3
4
2
3
1
0
2
3
1
2
2
1
3
4
2
3
39
9
2
3
1
2
2
3
1
2
+.
1
1
2
2
3
1
2
2
3
33
10
3
4
2
1
3
2
2
3
1
6.
2
1
3
4
2
1
3
2
39
11
3
2
2
3
1
2
2
1
1
2
7.
1
3
2
2
3
1
2
33
12
4
3
3
2
2
1
3
2
2
1
1
0
4
3
3
2
2
1
39
13
2
3
3
4
4
5
1
2
2
3
3
4
0
1
1
2
2
3
45
14
3
2
4
5
3
4
2
1
3
4
2
3
1
0
2
3
1
2
45
15
3
4
2
3
3
4
2
3
1
2
2
3
1
2
8.
1
1
2
39
16
4
5
3
2
4
3
3
4
2
1
3
2
2
3
1
0
2
1
45
17
4
3
3
4
2
3
3
2
2
3
1
2
2
1
1
2
0
1
39
18
5
4
4
3
3
2
4
3
3
2
2
1
3
2
2
1
1
0
45
В диагонали таблицы 6.2.4 размещены ВМ, реализующие заданную структуру ВС
для решения задачи, представленной граф-схемой на рисунке 6.2.8.
Рассмотрим построение нитей для граф-схемы алгоритма решаемой задачи с
учётом времени передачи информации. ВМ может обрабатывать и передавать
информацию. В этом случае время решения задачи сравнивается с временем передачи
информации и выбирается время, максимальное из этих двух. Граф-схема, представленная
на рисунке 6.2.8 в этом случае будет выглядеть следующим образом:
Рисунок 6.2.11. Схема представления обобщенного 3-х мерного гиперкуба 2х3х3.
Чёрными точками отмечены ВМ, использованные для решения поставленной задачи
В таблице 6.2.5 представлена матрица следования для граф-схемы примера
алгоритма решаемой задачи для ВС с распределённой памятью при использовании ВМ с
одновременной передачей информации.
193
4
4
1
5
3
3
3
2
3
5
3
•••
6
4
10
3
4
11
4
2
5
13
12
15
14
Рисунок 6.2.12. Граф-схема примера алгоритма решаемой задачи для ВС с распределённой
памятью с ВМ, осуществляющие одновременно обработку и передачу информации.
Таблица 6.2.5
1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
13
14
15
4
4
5
3
3
3
3
3
3
3
4
3
4
2
5
1
1
1
1
1
1
1
1
1
1
12
1
1
1
1
1
Построение нитей осуществляется аналогично как в случае ВС с общей памятью.
Вычисляются ранние сроки окончания выполнения операторов, затем строится их
диаграмма, как показано на рисунке 6.2.13, на основании матрицы следования
(таблица 6.2.5). Ранние сроки равны соответственно: t1,1=4, t1,2 =8, t1,3 =9, t1,4 =7, t1,5 =11,
t1,6=11, t1,7 =11, t1,8 =11, t1,9 =11, t1,10 =11, t1,11 =13, t1,12 =16, t1,13 =17, t1,14 =15, t1,15 =18.
9
8
7
9
8
7
6
5
6
5
4
3
4
2
1
3
1
15
14
11
2
10
13
12
Рисунок 6.2.13. Диаграмма ранних сроков окончания выполнения операторов для
граф-схемы 6.2.12 с учётом времён передачи информации между операторами в режиме
совмещения с обработкой
194
Для реализации граф-схемы, представленной на рисунке 6.2.12, как следует из
диаграммы рисунка 6.2.13, требуется семь процессоров (ВМ). Диаграмма получилась
достаточно компактной, так как отсутствуют многочисленные задержки, связанные с
передачей информации.
Так как структура ВС регулярна, то в матрице дистанций, представленной в таблице 6.2.6,
анализ на оптимальное размещение нитей не требуется. Для реализации цикла (нити 2, 5,
6, 7, 8, 9, 10) используем ВМ, отстоящие на дистанции 1 от нулевого ВМ. Реализовать
решение заданной задачи на структуре ВС типа циркулянта (12, 1, 5), у которого не
достаточно ВМ, имеющих неединичную
дистанцию, проблематично, так как
использование дистанции 2 требует дополнительные транзитные процессоры, которых в
данной структуре недостаточно. В данном случае можно пойти двумя способами. Первый
способ заключается в том, при заданном количестве ВМ увеличить количество связей.
Второй – заключается в увеличении количества процессоров. Рассматривается ВС типа
циркулянта (11, 1, 2. 5). Матрица дистанций для этой структуры представляется
таблицей 6.2.6.
Таблица 6.2.6.
0
0 +.
1 1
2 1
3 2
4 2
5 1
6 1
7 2
8 2
9 1
10 1
1 2
1 1
4.6. 1
1 7.
1 1
2 1
2 2
1 2
1 1
2 1
2 2
1 2
3
2
1
1
12.
1
1
2
2
1
1
2
4
2
2
1
1
0
1
1
2
2
1
1
5
1
2
2
1
1
8.
1
1
2
2
1
6
1
1
2
2
1
1
9.
1
1
2
2
7
2
1
1
2
2
1
1
15.
1
1
2
8
2
2
1
1
2
2
1
1
0
1
1
9
1
2
2
1
1
2
2
1
1
10.
1
10
1
1
2
2
1
1
2
2
1
1
3.
Вначале размещаются нити цикла алгоритма Т2 – Т10. Затем делается попытка
разместить все остальные нити. На отметке времени t=4 осуществляется обмен данными
между нитями Т1 и Т3,Т4. Вначале осуществляется обмен межу нулевым ВМ и первым
ВМ и нулевым ВМ и десятым. Нить 9 подключается к 6-му процессору. Размещение
нитей на вычислительных модулях ВС показаны в таблице 6.2.6. На главной диагонали
записываются номера нитей, отмеченных точкой. Номер строки или столбца определяет
номер используемого ВМ. Покажем размещение нитей рисунка 6.2.13 на ВС типа
циркулянта (11, 1, 2, 5), показанной на рисунке 6.2.14. Размещение загруженных ВМ
показано в виде закрашенных вершин граф-схемы.
Рисунок 6.2.14. Загрузка циркулянта (11, 1, 2, 5) нитями граф-схемы 6.2.8
195
6.2.4. Реализация диаграмм для общепринятых способов обмена данными
между ВМ вычислительной системы с распределённой памятью для
информационной граф-схемы
Как было отмечено выше, существует пять способов обмена данными между
процессорами: дифференцируемый, трансляционный, трансляционно-циклический,
конвеерно-параллельный и коллекторный. Дифференцируемый обмен – это обмен
«точка-точка». Реализация его на граф-схеме не представляет трудности. Трансляционный
обмен может быть реализован в виде изображения цикла, как показано на рисунке 6.2.8
(операторы 2, 5, 6, …, 10), хотя может использоваться и в других случаях, например, с
разным временем обмена данными по ветвям развёртки (см. рисунок 6.2.8,
операторы 11,…, 15).
Наиболее сложный в реализации обмен – трансляционно-циклический.
Изображение его в виде граф-схемы представлено на рисунке 6.2.15.
1
t
t
1
t
•••
2
t
N
t
t
1
•••
•••
t •••
N
t
1
q
t
N
N-1
111
Рисунок 6.2.15. Граф-схема алгоритма, реализующая трансляционно-циклический обмен
В рассматриваемом случае время передачи информации во всех ветвях равно t. На
n процессорах решается n2 операторов. построим диаграмму распределения операторов по
ВМ. Для определённости примем n=9.
10
9
8
7
6
5
4
3
2
1 1
0 1
9
8
7
6
5
4
3
2
9
8
7
6
5
4
3
9
8
7
6
5
4
3
4
9
8
7
6
5
9
8
7
6
9
8
2
1
7
9
6
5
4
3
2
1
5
4
3
4
3
2
1
3
2
1
2
1
1
2
9
8
7
6
5
8
9
10
Рисунок 6.2.16. Диаграмма размещения ВМ и операторов при организации,
трансляционно-циклического обмена. Символом « » обозначен процессор – передатчик
информации
196
Сложность реализации такого обмена заключается в том, что должно быть
обеспечена коммутация каждого процессора с каждым. Ситуация несколько облегчается
тем, что имеется периодичность обработки и обмена информацией
0
16
1
2
15
3
14
4
13
5
12
6
11
7
10
9
8
Рисунок 6.2.17. Структура ВС типа циркулянта (17,1, 2, 3, 5) при организации,
трансляционно-циклического обмена
Нить Т1 расположим, например, на нулевом ВМ и, как следует из таблицы
дистанций 6.2.7, она связана с процессорами {1, 2, 3, 5, 12, 14, 15, 16}, отстоящими на
дистанции один от нулевого процессора и, например,с шестым ВМ, отстоящим на
дистанции два. При требовании к ВС работать синхронно, множество процессоров
{1, 2, 3, 5, 12, 14, 15, 16} должны ожидать конца передачи, осуществляемой шестым ВМ.
Аналогичная ситуация возникает и при размещении оставшихся нитей. Безусловно, это
нежелательное явление можно было бы исключить, усложняя соответствующим образом
структуру ВС, взяв , например, циркулянт (17,1, 2, 3, 5, 7).
Таблица 6.2.7
0
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
0
0
1
1
1
2
1
2
2
2
2
2
2
1
2
1
1
1
1
1
0
1
1
1
2
1
2
2
2
2
2
2
1
2
1
1
2
1
1
0
1
1
1
2
1
2
2
2
2
2
2
1
2
1
3
1
1
1
0
1
1
1
2
1
2
2
2
2
2
2
1
2
4
2
1
1
1
0
1
1
1
2
1
2
2
2
2
2
2
1
5
1
2
1
1
1
0
1
1
1
2
1
2
2
2
2
2
2
6
2
1
2
1
1
1
0
1
1
1
2
1
2
2
2
2
2
7
2
2
1
2
1
1
1
0
1
1
1
2
1
2
2
2
2
8
2
2
2
1
2
1
1
1
0
1
1
1
2
1
2
2
2
9
2
2
2
2
1
2
1
1
1
0
1
1
1
2
1
2
2
10
2
2
2
2
2
1
2
1
1
1
0
1
1
1
2
1
2
11
2
2
2
2
2
2
1
2
1
1
1
0
1
1
1
2
1
12
1
2
2
2
2
2
2
1
2
1
1
1
0
1
1
1
2
13
2
1
2
2
2
2
2
2
1
2
1
1
1
0
1
1
1
14
1
2
1
2
2
2
2
2
2
1
2
1
1
1
0
1
1
15
1
1
2
1
2
2
2
2
2
2
1
2
1
1
1
0
1
16
1
1
1
2
1
2
2
2
2
2
2
1
2
1
1
1
0
Конвеерно-параллельный обмен целесообразно использовать при многократном
решении сложной задачи , представленной в виде программных модулей. Программные
197
модули располагаются в ВМ в нужной перенумерованной последовательности, Работа
осуществляется по периодам. Различаются периоды, имеющие чётные и нечётные номера.
Перенумерованы так же и ВМ. Вычислительные модули, имеющие нечётные номера,
осуществляют приём информации в момент работы нечётных периодов, а в этот момент
вычислительные модули, имеющие чётные номера, обрабатывают полученную
информацию. Наиболее простая структура ВС, которая может реализовать конвеернопараллельный обмен, представляется в виде кольцевой структуры, показанной на
рисунке 6.2.18.
0
1
7
2
6
5
3
4
Рисунок 6.2.18. Структура ВС типа циркулянт (8,1) при организации, конвеернопараллельного обмена. Жирной стрелкой показана передача данных в чётном периоде,
нежирной – передача данных в нечётном периоде
На диаграмме рисунка 6.2.19 по горизонтальной оси расположено восемь ВМ.
Каждый ВМ изображён четырьмя прямоугольниками в два ряда. Например, первый ВМ
нижним левым прямоугольником осуществляет приём данных в нечётный период,
верхним правым – передачу обработанных данных в чётный период. Время между
приёмом и передачей информации используется для обработки данных. Нить изображена
двумя строчками. Первая строка нити выполняется по нечётным периодам, вторая – по
чётным.
Рисунок 6.2.19. Диаграмма размещения ВМ и операторов при организации, конвеернопараллельного обмена. Жирными стрелками обозначена передача информации в нечётный
период в ВМ с нечётным номером
6.2.5. Вопросы к разделу 6.2
1. В чём отличие распределения операторов решаемой задачи для ВС с общим полем
памяти от ВС с разделяемой памятью.
2. Постройте матрицу дистанций для обобщённого четырёхмерного куба.
3. Как строятся нити на базе диаграмм ранних сроков окончания выполнения операторов?
4. Стратегии планирования использования ВМ при планировании логических операторов.
5. Как учитывается время обмена информацией при планировании вычислений для ВС с
распределённой памятью?
198
6. Способ построения матрицы следования для для граф-схемы алгоритма решаемой
задачи на ВС с распределённой памятью при использовании ВМ с одновременной
передачей информации.
7. При загрузке нитей в ВС чему следует отдать предпочтение: увеличению числа
процессоров в системе или увеличению степени вершин коммуникационной среды?
8. Изобразите диаграмму трансляционно-циклического обмена для пяти ВМ.
199
ГЛАВА 7. Исследование информационных граф-схем
решаемых задач с векторными весами для
планирования параллельных вычислений
7.1
Информационная граф-схема решаемых задач с векторными весами
вершин
7.1.1 Понятие об неоднородных системах
В вычислительной практике наряду с однородными системами получают всё
большее распространение неоднородные вычислительные системы (НВС). В
неоднородные ВС входят разнотипные вычислительные модули, объединённые с
помощью коммутационных сред, обеспечивающих обмен данными меду ними.
Программные модули, которые предполагается решать на разнотипных ВМ, имеют, как
правило, различные времена решения. В связи с этим, у каждой вершины граф-схемы
решаемой задачи появляется вектор времени решения рассматриваемой задачи. Размер
вектора времени решения определяется количеством типов ВМ. Пусть, например, НВС
имеет три типа ВМ, тогда задача, которую предполагается решать на рассматриваемой
неоднородной вычислительной системе можно представить в виде граф-схемы, как
показано на рисунке 7.1.1.
1
(2,8,4)
(1,5,  )
3
2
4
(4,  ,  )
5
(7,4,  )
(2,6,  )
Рисунок 7.1.1. Граф-схема задачи, которая будет решаться на неоднородной
вычислительной системе.
Как правило, веса составляющих вектора j-й вершины p j (pj,1, pj,2, …, pj,n)
упорядочиваются следующим образом: составляющая вектора pj,1 определяет время
решения программного модуля на первом типе ВМ, pj,2 – на втором и т.д. Символ «  »
обозначает, что рассматриваемый модуль на данном типе процессора не может
выполняться. Так, на рисунке 7.1.1 оператор 2 не может быть выполнен на третьем типе
процессора. Для исследования граф-схем, предназначенных для решения на НВС,
упорядочим составляющие векторов веса в порядке неубывания, не теряя при этом
информацию о принадлежности составляющей к типу ВМ, исключив при этом
символ «  », уменьшив при этом размерность соответствующего вектора. Преобразуем
граф-схему с векторными весами в граф-схему со скалярными весами, используя
следующее правило: каждая j-я вершина с векторным весом образует n вершин, где n
размерность вектора p j . Преобразованная граф-схема показана на рисунке 7.1.2.
Выделяя вершины с одинаковыми типами ВМ, получим граф-схемы частей задачи,
решаемых на соответствующих типах ВМ. Эти граф-схемы будем обозначать как
G=(X, P, I, Г), где i  I – тип ВМ, за которым закреплён оператор j  X и называть
200
G - выборкой граф-схемы G. При анализе векторных граф-схем, с помощью методов,
применяемых для скалярных граф-схем, сложность решения задачи возрастает в
n
Q =qj ,
j 1
где qj – размерность j-ого вектора, n – количество векторов в рассматриваемой
граф-схеме. Для рассматриваемой граф-схемы рисунка 7.1.2 количество G-выборок
составит G=3*2*2*1*2=24. В G-выборках каждый оператор закреплён за определённым
процессором.
1.1
1(1)
4(1)
2(1)
2.2
2.1
4.1
4(3)
1.2
5(2)
2(1)
4(2)
1.3
3.1
7(1)
6(2)
5.1
8(2)
3.2
5.2
Рисунок 7.1.2. Преобразованная граф-схема задачи с векторными весами в граф-схему со
скалярными весами вершин
Для уменьшения сложности решения задач, представленных векторными графсхемами, путём сведения их решения к Q задач со скалярными весами небезинтересной
является теорема об уменьшении количества скалярных граф-схем для данной векторной
граф-схемы.
Теорема 7.1.1
Если
1) {Ni}, i=1, …, k, – набор ВМ вычислительной системы,
2) оператор z входит только в одно полное множество ВНО с числом
операторов r,
3) компоненты веса вершины оператора z упорядочены по не убыванию
так, что pz1  pz2  pz,s   , pz,s+1= … = pz,k=  при s < k, где s – количество
процессоров способных выполнить данную операцию.
4) существует положительное w < s такое, что при w = 1, 0  r  Ni ,
а при
w > r,
w 1
w
i 1
i 1
 Ni  r   Ni ,
то при исследовании и выполнении планов данного последовательного алгоритма
можно положить pz,w+1=…=pz,w+s=  , что приводит к исключении процессоров
соответствующих типов, начиная с номера w+1, из рассмотрения при поиске вариантов
назначения оператора z.
Доказательство. Очевидно, что если исключить оператор z, входящий в одно
полное множество ВНО, оставив неизменными моменты окончания других операторов,
входящих в это множество, оператор z не выполнять, то общее время решения задачи не
увеличится. Если время решения задачи оператора z на одном из r процессоров не больше,
чем на каждом из
s
   Ni  r
i 1
201
вычислительных модулей, то размещение оператора z на одном из  ВМ заставит
простаивать ВМ из множества z. Теорема доказана.Таким образом, при определённых
условиях, имеется возможность исключить некоторые типы процессоров, что, как
правило, приводит к сокращению времени решения задачи.
Рассмотрим пример.
1
(1,3,2)
(3,  ,1)
3
2
(5,5,1) 4
6
(  ,2,3)
5
(6,5,  )
(1,2,2)
Рисунок 7.1.3. Граф-схема задачи с векторными весами
В данном примере рассматривается ВС с тремя типами процессоров по одному
процессору каждого типа. Образуется три множества ВНО : ВНО1 = {1}, ВНО2 = {(2), 3},
ВНО3 = {(4), 5}. Для ВНО1: r=1, N1=1 и неравенство пункта 4 теоремы выполняется, тогда
в операторе 1 целесообразно взять веса (1,  ,  ). Для ВНО2: не выполняется условие (3)
теоремы – соответствующие веса не упорядочены. Для ВНО3: : r=2, N1=1, w=2.
неравенство пункта 4 запишется в виде: 1  2  2. Для четвёртой вершины целесообразно
выбрать веса – (1, 1,  ). Общее число выборок для граф-схемы, представленной на
рисунке 7.1.3 до применения теоремы 7.1.1 равно R=3*2*2*3**3*2=216, после
применения теоремы – R =1*2*2*2*3*2=48. Если к каждой выборке применять
рассмотренные выше методы исследования для однородных ВС, то трудоёмкость
определения параметров неоднородных ВС после применения теоремы 7.1.1 сокращается
почти в пять раз. В отдельных случаях для анализа неоднородных ВС применяются
младшие G-выборки
графа G*, поэтому могут оказаться полезными следующие
определения.
7.1.2. Основные определения, используемые для неоднородных ВС
Рассмотрим основные определения, используемые для неоднородным
вычислительных систем.
Определение 7.1.1. Минимальную составляющую вектора веса вершины  графсхемы G назовем младшим скалярным весом этой вершины.
Определение 7.1.2. G-выборку графа-схемы G*, составленную из вершин с
младшими скалярными весами, назовем младшей G-выборкой граф-схемы G*.
Для заданного алгоритма, представленного набором операторов j=1, .., m и
неоднородной ВС, имеющей k типов процессоров с N i - количеством процессоров i-го
типа, i=1, …, k и известными сроками окончания выполнения операторов (t1 ,..., tm )  M T
определим плотность загрузки для i-го типа процессора при условии, что известны t ji –
сроки окончания выполнения j-ого оператора на i-м типе процессора, t ji  М T , всего таких
операторов ki .
Определение 7.1.3. Плотностью загрузки для i-го типа процессора, найденной
ki
для значений (t1 ,..., t m )  M T , назовем величину, PZ i (t j1 ,..., t jk , )   OP (t j , ), где
i
 1
202

1, если  [(t j  p j ), t j ]
OP (t j , )  

0, если  [(t j  p j ), t j ]
Определение 7.1.4. Функцию
b
Z i (t j1 ,..., t jki , a, b)   PZ i (t ji ,..., t jki , )d
a
назовем
загрузкой отрезка [a,b], входящей в интервал [0,T] для i-го типа процессора.
Определение 7.1.5. Функцию Z i(T ) (a, b)  min Z i (t j1 ,..., t j ki , a, b) назовем минимальной
загрузкой отрезка [a,b] для i-го типа процессора.
При определении Z i(T ) (a, b) по аналогии с алгоритмом 6.1.3 необходимо учитывать
только те операторы, которые выполняются на i-м типе процессора.
Алгоритм 7.1.1.
1. С помощью алгоритмов 6.1.1 и 6.1.2 определяем t1, j и t2, j (T ) – ранние и поздние
сроки окончания выполнения операторов.
2. Вычислить i:=5.
3. Вычислить Z i(T ) (a, b)  0 .
4. Анализируем последовательность операторов { ji },  1,...,i , принадлежащих iму типу процессора.
5. Вычислить Zi(T ) (a, b)  Zi(T ) (a, b)  min{  (t1, j  a),  (b  t2, j (T )  p j ), p j , (b  a)} .
6. После перебора всех операторов, выполняемых на i-м типе процессора, определяем
загрузку i-го типа процессора.
7. Переходим на вычисление загрузки следующего типа процессоров i=i+1. Идем на
шаг 3.
8. После перебора всех значений i получим загрузку всех типов процессоров.
Пример. Определение минимальной загрузки процессоров первого и второго типов
для граф-схемы, представленной на рисунке 7.1.4.
Ранние и поздние сроки окончания выполнения операторов равны: t1, j ={1,4,2,3,6},
t2, j (8)  {3,6,8,8,8}, j=1, …, 5. Эти значения и заданный порядок следования операторов в
граф-схеме определяет многоугольник МТ. Определим в точке (2, 5, 6, 5, 8)  М Т PZ1 и
PZ2. Согласно определению 7.1.3 – PZ1=1+1+1=3, PZ2=1+1=2. Загрузка отрезка, по
определению 7.1.4, составит: Z1(2, 5, 6, 5, 8, 1, 6)=2, Z2(2, 5, 6, 5, 8, 1, 6)=5.
1
1
2
3
3
5
1
4
2
2
Рисунок 7.1.4. Пример граф-схемы решаемой задачи на неоднородной ВС. Время
решения задачи Т=8. Закрашенные вершины закреплены за первым типом процессора.
Используя вышеприведенные определения, сформулируем теоремы для оценки
требуемого количества процессоров N i , и для оценки времени решения задачи, на наборе
процессоров различного типа.
203
Теорема 7.1.2. Об оценке времени решения задачи на неоднородной ВС и
определение необходимого количества наборов процессоров.
Пусть каждый оператор данного алгоритма может быть выполнен процессором
одного и только одного типа из множества типов i=1,…,k. Тогда для того, чтобы Т
было наименьшим временем реализации данного алгоритма, состоящего из множества
{ N i } процессоров, либо для того, чтобы набор { N i } был достаточен для выполнения
данного алгоритма за время Т необходимо, чтобы для любого отрезка времени
[a, b]  [0, T ] выполнялось соотношение: Zi(a,b)≤Ni(b-a).
Теорема 7.1.3. Об уточнении оценки времени выполнения алгоритма на наборе
процессоров { N i }.
Пусть алгоритм задан информационным графом со скалярными весами вершин, и
каждый оператор может быть выполнен процессором одного и только одного типа из
множества типов i=1,…,k. Пусть ВС состоит из процессоров указанного типа. Пусть
далее T1 оценка реализации данного алгоритма на ВС, для которого на некотором
отрезке [a, b]  [0, T ]
Zi (a, b)  Ni (b  a)  d  0 .
Тогда наименьшее время выполнения Т рассматриваемого алгоритма
удовлетворяет соотношению
Т>Т1+d/Ni.
На основе этих теорем строятся алгоритмы оценок необходимого набора
разнотипных процессоров для решения данной задачи за время Т, и оценки необходимого
времени решения рассматриваемой задачи на данном наборе процессоров.
Алгоритм 7.1.2. (Оценка минимального количества наборов процессоров N i , i=1,…,m,
необходимых для выполнения заданного алгоритма за время Т)
1. Приравняем I:=1.
2. Положим N i =0.
3. Последовательно берутся j-е интервалы как в алгоритме 6.1.2 [a, b]  [0, T ] :
[0,1], [0,2], [1,2],…, [T-1, T], j=1, …, r.
Z i(T )
j
(T )
Z
(
a
,
b
)
N

]
[.
4. По алгоритму 7.1.1 вычисляем i
и затем i
ba
5. Если N i j >Ni, то Ni= N i j .
6. Увеличиваем i=i+1, если i > m то конец алгоритма, иначе переход на шаг 2.
Алгоритм 7.1.3. (Оценка минимального времени Т выполнения алгоритма на наборе
процессоров)
{ N i }, i = 1,…, m
1. Вычислить i:=1,Т=0.
2. Вычислить Ti : Tкр .
3. Последовательно берутся j-е интервалы, как в алгоритме 6.1.2 : [a,b]  [0,Ti]:
[0,1], [0,2], [1,2],…, [Ti-1, Ti], j=1, …, r для шагов 4, 5, 6, 7, 8.
4. Используя алгоритм 7.1.1 вычислить Z i(Ti ) (a, b) .
5. Вычислить di=Z i(Ti ) (a, b)  N i (b  a) .
d
6. Если di  0 , то Ti : Ti  ] i [ .
Ni
204
di
[ ,   1,...,i .
Ni
8. Если Тi >T, то Т=Тi.
9. Вычислить i=i+1,если i>m то конец алгоритма, иначе переходим на шаг 3.
7. t 2j (Ti )  t 2j (Ti )]
7.1.3. Вопросы к разделу 7.1
1. В чём преимущества и недостатки неоднородных вычислительных систем?
2. С какой целью осуществляется преобразование векторных граф-схем в набор
скалярных граф- схем?
3. Покажите на примере полезность от применения теоремы 7.1.1.
4. Когда может быть полезна G выборка граф-схемы G*?
5. В чём отличие определений плотностей загрузок для однородной и неоднородной ВС?
6. Объясните, почему согласно рисунку 7.1.4
Z1(2, 5, 6, 5, 8, 1, 6)=2,
а Z2(2, 5, 6, 5, 8, 1, 6)=5.
7. Объясните, почему в алгоритме 7.1.2 в пункте 3 взяты те же интервалы, что и в пункте 2
алгоритма 6.1.4.
205
Литература
1. Хорошевский В.Г. Архитектура вычислительных систем. Изд. МГТУ им. Баумана,
Москва, 2005 г. 511 с. : ил.
2. Корнеев В. В. Параллельные вычислительные системы. -М.: Гелиос АРВ,2004. -487
с. : ил.
3. Барский А. Б. Параллельные процессы в вычислительных системах. - М.: Радио и
связь, 1990 - 256с. : ил.
4. Водяхо А.И., Горнец Н.Н., Пузанков Д.В. Высокопроизводительные системы
обработки данных. -М.: Высшая школа. 1997. - 150с. : ил.
5. http://www.specbench.org/osg/cpu2000/results/.
6. http://www.netlib.org/benchmark/performance.ps.
7. http://www.top500.org.
8. ScaLAPACK. http://www.netlib.org./scalarpack/scalarpack_home.html.
9. Petitet A., Whaley R., Dongarra J., Cleary A. HPL – A Portable Implementation of the
High – Performance Linpack Benchmark for Distributed – Memory Computers.
http://www.netlib.org/master_counts2.html#benchmark/hpl.
10. Batcher K. STARAN Parallel Processor System Hardware. NCC . Pp. 405-410, 1974.
11. Амамия М., Танака Ю. Архитектура ЭВМ и искусственный интеллект.- М.: Мир.
1993. 397 с.
12. Воеводин В. В., Воеводин Вл. В. Параллельные вычисления. Санк-Петербург:
БХВ-Петербург, 2002.-600с. : ил.
13. Tera Computer Company Completes Desing of Breakthrough Multiprocessor Chip.
http://www.tera.com.
14. Exemplar SPP1000 System. Technical Summary. Convex Computer Corporation, 3000
Waterview Parway, P.O.BOX 833851,Richardson, Texas 75083-3851, 1994.p.25.
15. ZabrodinA.V., Levin V.K., Korneev V.V. The massively parallel computer system
MBC-100. – Lecture Notes in computer Science, № 964. Parallel Computing Technologies.
Third International Conference, PaCT – 95, s - Petersburg, Russia, Sept. 1995, Springer. Pp.
341-355/
16. Smith J.E. Decoupled access/execute computer architectures. Proc. of IEEE.Pp.112119,1983.
17. Sohi G., Roth A. Speculative Multithreaded Processor. Computer. Vol. 34. 2005. - № 4.
18. Hennessy J. The Future of Systems Research. Computer. Pp.27-33.1999.-№ 8.
19. IEEE. Computer Society.IEEE Standart for Scalable Coheren Interface (SCI). IEEE Std
1596-1992. New-York, August, 1993.
20. http://www.myri.com.
21. http://www.quadrics.com.
22. Kol R., Ginosar R. Kin: A High Perfomance Asynchronous Processor Architecture.
Proc. of International Conference on Supercomputing. Pp. 433-440. July 13-17, 1998,
Melbourne, Australia.
23. http://parallel.ru/tech/tech_dev/par_libs.html
24. http://www.kai.com/parallel/kappro/guide/
25. Фадеев Д.К., Фадеева Д.Н. Вычислительные методы линейной алгебры. – М.:
Физматгиз, 1960. С. 656.
26. Кун С. Матричные процессоры на СБИС. – М.: Мир, 1995. С. 672.
27. Седухин С. Г. Параллельно-поточная интерпретация метода Гаусса.
Вычислительные системы с программируемой структурой. (Вычислительные системы 94).
– Новосибирск: ИМ СОАН СССР, 1982. С. 70-80.
28. http://parallel.ru/tech/tech_dev/mpi.html
206
29. Антонов А.С. Параллельное программирование с использованием технологии
MPI: Учебное пособие. –М.: Изд-во МГУ, 2004.-71 с.
30. Криницкий Н.А., Миронов Г.А., Фролов Г.Д. Программирование и
алгоритмические языки. –М.: Физматгиз, 1979.-509 с.
31. Фаронов В.В. TurboPascal 7.0. Практика программирования. Учебное пособие. –
М.: «Нолидж», 1997.-432 с., ил.
32. Корн Г., Корн Т. Справочник по математике для научных работников и
инженеров. –М.: Физматгиз, 1973.-832 с.
33. Ильин В.П.. Методы неполной факторизации для решения алгебраических систем.
– М.: Наука, 1995. – 287 с.
34. Старченко А.В. // Вестник Томского государственного университета.− 2003. −
№10. − С. 70−80.
35. Данилкин Е.А. // Третья Сибирская школа-семинар по параллельным вычислениям
/ Под ред. проф. А.В. Старченко. Томск: Изд-во Том. ун-та, 2006. С. 95 – 101.
207
Download