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

Оптимизирующие преобразования программ. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
849 Кб
Скачать

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ

Федеральное государственное автономное образовательное учреждение высшего образования

«ЮЖНЫЙ ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ»

Б. Я. Штейнберг

Оптимизирующие преобразования программ

Учебное пособие

Ростов-на-Дону – Таганрог Издательство Южного федерального университета

2025

1

УДК 004.415.3:519.681.3(075.8) ББК 32.972.11+32.971.32-043я73

Ш88

Печатается по решению кафедры алгебры и дискретной математики Института математики, механики и компьютерных наук им. И. И. Воровича Южного федерального университета

(протокол № 1 от 11 января 2025 г.)

заведующий кафедройРецензентыинформатики: и информационных таможенных технологий Ростовского филиала

Российской таможенной академии, доктор физико-математических наук,

доцент О. Е. Кудрявцев;

доцент кафедры информатики и вычислительного эксперимента Южного федерального университета,

кандидат физико-математических наук, доцент В. А. Нестеренко

Ш88 ШтейнбергОптимизирующие, Б. Я. преобразования программ : учебное пособие / Б. Я. Штейнберг ; Южный федеральный университет. – Ростов-на-Дону ; Таганрог : Издательство Южного федерального университета, 2025. – 122 с.

ISBN 978-5-9275-4947-4

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

Предназначено для студентов направлений подготовки «Прикладная математика и информатика» и «Фундаментальная информатика и информационные технологии».

ISBN 978-5-9275-4947-4 УДК 004.415.3:519.681.3(075.8) ББК 32.972.11+32.971.32-043я73

© Южный федеральный университет, 2025 © Штейнберг Б. Я., 2025 © Оформление. Макет. Издательство

Южного федерального университета, 2025

2

ОГЛАВЛЕНИЕ

ВВЕДЕНИЕ.................................................................................................................................

5

1. СВЕДЕНИЯ ИЗ ТЕОРИИ ГРАФОВ.............................................................................

7

2. ПРЕОБРАЗОВАНИЯ ПРОГРАММ.............................................................................

9

2.1. Программные зависимости и базовые преобразования.......................

9

2.1.1. Модель рассматриваемых программ..................................................

9

2.1.2. Управляющий граф программы............................................................

10

2.1.3. Информационная зависимость

 

и граф информационных связей.....................................................................

15

2.1.4. Граф зависимостей по данным ............................................................

21

2.1.5. Решётчатый граф программы................................................................

21

2.2. Базовые преобразования программ.............................................................

23

2.2.1. Базовые понятия о преобразованиях программ.........................

23

2.2.2. Пустой оператор. Удаление и вставка операторов.....................

24

2.2.3. Удаление мёртвого кода. Поиск и удаление

 

недостижимых и неиспользуемых по управлению операторов......

28

2.2.4. Удаление оператора (заголовка) цикла............................................

29

2.2.5. Удаление условных операторов...........................................................

32

2.2.6. Приведение выражения к стандартному виду

 

(«приведение подобных»)...................................................................................

33

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

35

2.3.1. Перестановка фрагментов (блоков) программы..........................

35

2.3.2. Подстановка вперёд..................................................................................

43

2.3.3. Вынос вычисления выражений и замена

 

общих подвыражений..........................................................................................

48

2.4. Преобразования циклов.....................................................................................

51

2.4.1. Раскрутка цикла...........................................................................................

51

2.4.2. Канонизация циклов..................................................................................

55

2.4.3. Перестановка блоков в цикле...............................................................

56

2.4.4. Расщепление цикла....................................................................................

57

2.4.5. Разрыв итераций, гнездование цикла и подобные

 

им преобразования...............................................................................................

59

3

2.4.6. Развёртка цикла...........................................................................................

63

2.4.7. Расщепление вершин (Введение временных массивов)..........

65

2.4.8. Растягивание скаляров и расширение массива...........................

66

2.4.9. Разбиение цикла..........................................................................................

69

2.4.10. Приведение цикла к разбиваемому виду.....................................

73

2.4.11. Использование перестановки операторов

 

для разбиения цикла.............................................................................................

73

2.4.12. Использование расщепления вершин

 

для разбиения цикла.............................................................................................

76

2.4.13. Повышение размерности массивов

 

для разбиения циклов..........................................................................................

78

2.4.14. Слияние циклов.........................................................................................

79

2.4.15. Инверсия цикла.........................................................................................

82

2.4.16. Вынос оператора из цикла ..................................................................

85

2.4.17. Индуктивные и охватывающие переменные в цикле.............

90

2.5. Преобразования неканонических циклов..................................................

95

2.5.1. Сдвиги границ циклов..............................................................................

96

2.5.2. Расщепление с перестановкой.............................................................

96

2.6. Преобразования функций..................................................................................

97

2.6.1. Инлайнинг.......................................................................................................

97

2.6.2. Уменьшение количества параметров функции............................

97

3. РАСПАРАЛЛЕЛИВАНИЕ.............................................................................................

99

3.1. Параллельные процессы.....................................................................................

99

3.2. Параллельные вычислительные архитектуры..........................................

99

3.3. Виды распараллеливания программ..........................................................

101

3.4. Распараллеливание циклов на архитектуру SIMD...............................

102

3.5. Распараллеливание конкатенации блоков

 

на архитектуру MIMD.........................................................................................

107

3.6. Распараллеливание циклов на архитектуру MIMD..............................

108

3.7. Асинхронное распараллеливание циклов

 

с зависимыми итерациями..............................................................................

111

3.8. Ошибочные представления о распараллеливании.............................

114

4. ПРИМЕРЫ КОНТРОЛЬНЫХ ЗАДАНИЙ..........................................................

117

4.1. Пример контрольного задания на построение графа

 

информационных связей.................................................................................

117

4.2. Пример тестовых вопросов по преобразованиям программ........

118

ЛИТЕРАТУРА.......................................................................................................................

120

4

ВВЕДЕНИЕ

В высокопроизводительных вычислениях нуждаются многие приложения: системы искусственного интеллекта, криптографии, метагеномики. В повышении производительности нуждаются задачи прогноза погоды, создания новых материалов с заданными свойствами, математического моделирования изменения климата, проектирования сложных систем и пр. Но быстрые программы нужны не только для высокопроизводительных вычислительных систем. Они нужны для роботизированных устройств, особенно беспилотных транспортных средств, а для массовых роботов вычислительные системы должны потреблять мало энергии, иметь небольшой вес и реализацию на дешёвой микросхеме, при этом они должны быстро распознавать изображения высокого разрешения (много пикселей) и сигналы высокого качества.

С другой стороны, многие программы используют значительно менее 1 % возможностей процессора (пиковой производительности). Оптимизирующие компиляторы плохо оптимизируют код [29], и проблема отставания развития программного обеспечения от развития микросхем и компьютеров становится всё более острой. Поэтому оптимизирующие преобразования программ нужны не только для разработки компиляторов, но и для «ручной» разработки быстрых программ.

Оптимизирующим преобразованиям программ посвящено много книг и статей [2, 4, 6, 8, 9, 16, 19, 21, 23–28, 30–33]. Разработ-

ки распараллеливающих преобразований программ опираются на архитектуры параллельных вычислительных систем и технологии параллельного программирования [1, 3, 5, 10, 12–15, 22]. Но новые программные приложения иногда требуют новых преобразований. В данном учебном пособии предпринята попытка собрать преобразования в стройную систему, соответствующую требованиям

5

ускорения многих прикладныхВведениепрограмм, с которыми автору пришлось сталкиваться.

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

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

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

6

1.СВЕДЕНИЯ ИЗ ТЕОРИИ ГРАФОВ

Вэтом параграфе кратко приводятся сведения из теории графов, необходимые для изложения основного материала. Более подробно теорию графов можно изучать по книгам [7, 11, 17, 18, 20] и другим источникам.

Граф – это множество точек, называемых вершинами, и отрезков, называемых рёбрами, которые эти вершины соединяют. Обозначают граф G(X, U), где G – это имя графа, X – множество вершин, U – множество рёбер (x , x ), x , x X .

Графы различают 1ориентированные2 1 2 и неориентированные. Для неориентированных графов отождествляются пары (x , x ) и (x , x ). Для ориентированных графов пары (x , x ) и (x , x ) 1разли2 - чаются2 1 и, как правило, называются дугами (а не1 рёбрами2 2 ).1

Вершины x , x называются концевыми или инцидентными к ребру (дуге) (x , x )1. Эти2 же вершины называются смежными друг к другу.

Степень1 вершины2 – это количество рёбер, инцидентных данной вершине.

Если в ориентированном графе есть дуга (x , x ), то говорят, что эта дуга выходит из вершины x и входит в вершину1 2 x .

Количество дуг, выходящих из1 вершины x, называется2 полустепенью исхода, а количество дуг, входящих в вершину x, – полустепенью захода.

Очевидно, сумма полустепеней исхода всех вершин ориентированного графа равна сумме полустепеней захода всех вершин.

Источник – это вершина в ориентированном графе, в которую не входит ни одна дуга.

Сток – это вершина в ориентированном графе, из которой не выходит ни одна дуга.

Путь в неориентированном графе – это такая чередующаяся последовательность вершин и рёбер, что для каждого ребра в

7

последовательности соседние1. Свед ниясизнимтеориивершиныграфов – это обе концевые вершины данного ребра.

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

Цикл в неориентированном графе – это путь, у которого начальная и конечная вершины совпадают.

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

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

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

Далее понадобится понятие «фактор-граф».

Пусть множество вершин графа разбито на подмножества. Фактор-граф – это граф, вершинами которого являются подмножества вершин исходного графа. Дуга (или ребро) соединяет пару вершин, если между соответствующими подмножествами была дуга (ребро).

Часто рассматривается фактор-граф по компонентам сильной связности (иногда называется «конденсация»). Известна (несложно доказывается) теорема о том, что фактор-граф по компонентам сильной связности бесконтурный.

8

2.ПРЕОБРАЗОВАНИЯ ПРОГРАММ

2.1.Программные зависимости и базовые

преобразования

Данная 2работа.1.1. Модельориентированарассматривнаемыхпреобразованияпрограмм программ языка С, и большинство примеров приводятся на этом языке или на псевдокоде, близком к С. Но предлагаемые преобразования могут использоваться и для других программ языков. Поэтому попытаемся описать требования (модель) к языкам, к которым могут относиться предлагаемые преобразования.

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

• операторы присваивания;

• блочные операторы (операторные скобки);

• условные операторы;

• циклы со счётчиком (параметром, считающим итерации);

• операторы GOTO безусловного перехода на метку;

• пустые операторы;

• операторы вызова подпрограммы (процедуры или функции). Данные описываются только константами, скалярными пере-

менными и массивами.

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

9

ячеек памяти). Последовательность2. Преобраз вания программчтения единиц языка определяется семантикой языка программирования. Если две единицы языка могут прочитаться при некотором исполнении программы одна после другой так, что между ними не читается ни одна другая единица языка, то говорят, что они связаны передачей управления.

У программы выделяются входные, промежуточные и выходные данные.

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

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

В примерах будут фрагменты программ на языке, подобном языку С.

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

Управляющий2.1.2граф. Управляющийпрограммыграф– этопрограммыодна из основ преобразования программ. Даже если в описании преобразования управляющий граф не упоминается, то он, как правило, подразумевается. В явном или неявном виде управляющий граф присутствует во внутренних представлениях оптимизирующих/распараллеливающих компиляторов.

Вершины управляющего графа – это некоторые элементы языка программирования (чаще всего операторы, но могут быть слова вроде «else», «end», …), а дуги – это передачи управления.

Отметим, что ранее в литературе в качестве вершин управляющего графа предлагалось использовать только операторы программы. Такой подход вполне удобен для программ языка ФОРТРАН, но уже неудобен для языка Паскаль, в котором циклу с постусловием «repeat-until» пришлось бы сопоставлять одну вер-

10

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