Исследование и оптимизация применения трасс исполнения приложения для статической бинарной трансляции под RISC архитектуры тема диссертации и автореферата по ВАК РФ 05.13.11, кандидат наук Лисицын Сергей Алексеевич

  • Лисицын Сергей Алексеевич
  • кандидат науккандидат наук
  • 2022, ФГАОУ ВО «Московский физико-технический институт (национальный исследовательский университет)»
  • Специальность ВАК РФ05.13.11
  • Количество страниц 106
Лисицын Сергей Алексеевич. Исследование и оптимизация применения трасс исполнения приложения для статической бинарной трансляции под RISC архитектуры: дис. кандидат наук: 05.13.11 - Математическое и программное обеспечение вычислительных машин, комплексов и компьютерных сетей. ФГАОУ ВО «Московский физико-технический институт (национальный исследовательский университет)». 2022. 106 с.

Оглавление диссертации кандидат наук Лисицын Сергей Алексеевич

Введение

Глава 1. Обзор существующих технологий бинарной трансляции

1.1 Процесс оптимизации приложений

1.2 Бинарная оптимизация

1.3 Обзор бинарного оптимизатора BOLT

1.3.1 Получение профильной информации для оптимизатора BOLT

1.3.2 Пример оптимизации

1.3.3 Результаты тестирования BOLT на архитектуре х86

1.3.4 Поддержка ARM архитектуры бинарным оптимизатором

Глава 2. Получение профильной информации из трасс

исполнения

2.1 Получение трасс исполнения приложений

2.2 Моделирование предсказателя переходов

2.3 Проверка профильной информации, полученной с трасс исполнения

2.4 Описание синтетических тестов

2.5 Результаты тестирования

2.6 Вывод по главе

Глава 3. Улучшения бинарного оптимизатора BOLT

3.1 Оптимизация длинных переходов

3.2 Исправление преобразования таблиц переходов

3.3 Верификация бинарной оптимизации

3.4 Результаты тестирования модифицированного оптимизатора

3.5 Вывод по главе

Глава 4. Бинарные оптимизации на основе трасс исполнения

4.1 Проблемы оптимизации с профильной информацией

4.2 Мул ьти профильны и анализ трасс исполнения

4.3 Дублирование кода на основе мультипрофиля

Стр.

4.4 Результаты тестирования оптимизации дублирования

4.5 Вывод по главе

Заключение

Список литературы

Список рисунков

Список таблиц

Приложение А. Программный код основных синтетических

тестов

Приложение Б. Ассемблерный код демонстрационного примера

Приложение В. Акты о внедрении

Рекомендованный список диссертаций по специальности «Математическое и программное обеспечение вычислительных машин, комплексов и компьютерных сетей», 05.13.11 шифр ВАК

Введение диссертации (часть автореферата) на тему «Исследование и оптимизация применения трасс исполнения приложения для статической бинарной трансляции под RISC архитектуры»

Введение

В настоящее время задача улучшения производительности вычислительных машин приобретает всё большее значение. В 2021 году две трети населения планеты ежедневно использовали мобильные вычислительные устройства, а их количество стало больше 4 миллиардов. Уменьшение времени работы на конкретных задачах или увеличение соотношения производительность/энергопотребление приносит большой выигрыш в масштабе количества устройств.

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

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

/ К / К / N / К / Optimized Executable Binary

Source Code 1 Parser / Compiler IR I Code Gen. ,> Object Files 1 Linker / Executable Binary Binary Opt/

1/ 1/' 1/ v

Рисунок 1 Процесс трансляции исходного кода в оптимизированный бинарный файл

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

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

Для архитектуры х86 существует специальная аппаратная поддержка, позволяющая собирать профильную информацию во время исполнения приложения - LBR (Last Branch Record). Для ARM архитектуры аналог данной технологии существует, но не поддерживается всеми процессорами, что создаёт проблемы для оптимизаций приложений с учётом профиля исполнения. Произвести статическую инструментацию приложения не всегда является возможным, например, в случае отсутствия исходного кода или информации о символах и релокационных данных в бинарном файле. Поэтому актуальной задачей является разработка метода получения профильной информации для ARM архитектуры и дополнительных бинарных оптимизаций.

Целью данной работы является изучение и оптимизация существующих инструментов статической бинарной трансляции под RISC архитектуры. Основной целевой платформой является одна из наиболее распространенных на данный момент RISC архитектур - ARM. Основным классом оптимизаций являются оптимизации, использующие профильную информацию исполнения приложения.

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

1. Исследовать существующие статические бинарные трансляторы под RISC архитектуры.

2. Разработать универсальный метод получения профильной информации под RISC архитектуры.

3. Разработать ПО для получения профильной информации приложения по трассе его исполнения.

4. Разработать методы улучшения статического бинарного транслятора.

5. Реализовать наиболее перспективные методы улучшения бинарного оптимизатора.

6. Разработать новые оптимизации на основе внедренных методов и улучшений.

7. Протестировать разработанные методы на реальных приложениях под RISC архитектуру.

Тема и содержание диссертационной работы соответствует паспорту научной специальности 05.13.11 - Математическое и программное обеспечение

вычислительных машин, комплексов и компьютерных сетей, в частности, пунктам:

п i ............. Модели, методы и алгоритмы проектирования и анализа программ

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

п_ з _ Модели, методы, алгоритмы, языки и программные инструменты для организации взаимодействия программ и программных систем.

Научная новизна:

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

2. Была реализована полноценная поддержка бинарного оптимизатора BOLT для ARM архитектуры, необходимая для проведения тестовых замеров на целевых приложениях, в то время как исходная версия BOLT не поддерживает оптимизацию нужных приложений.

3. Был разработан специальный формат, описывающий преобразования исполняемого файла в оптимизированный.

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

5. Был создан алгоритм мультипрофильного анализа, выделяющий профили приложения на основе трасс исполнения. На его основе реализована оптимизация копирования кода.

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

Результаты данной работы также внедрены в кафедральный курс «Современные методы разработки компиляторов» кафедры микропроцессорных технологий в интеллектуальных системах управления МФТИ.

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

Результаты, выносимые на защиту:

1. Метод получения профильной информации для бинарного оптимизатора BOLT из трасс исполнения приложений.

2. Алгоритм оптимизации длинных переходов при работе бинарного оптимизатора BOLT.

3. Алгоритм верификации оптимизированных бинарным оптимизатором BOLT файлов.

4. Алгоритм мультипрофильного анализа трасс исполнения приложений.

5. Алгоритм дублирования кода на основе мультипрофильного анализа трасс исполнения приложений.

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

Апробация работы. Результаты диссертационной работы докладывались на следующих научно-технических конференциях:

1. 63-й всероссийской научной конференции московского физико технического института (государственного университета, Москва, ноябрь 2020 г.

2. Международном конгрессе «Современные проблемы компьютерных и информационных наук», Москва, ноябрь 2021 г.

3. 64-й всероссийской научной конференции московского физико технического института (государственного университета, Москва, ноябрь 2021 г.

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

Публикации. Основные результаты по теме диссертации изложены в 5 печатных изданиях, 2 из которых изданы в журналах, рекомендованных ВАК, 3 и тезисах докладов.

Объем и структура работы. Диссертация состоит из введения, 4 глав, заключения и 3 приложений. Полный объём диссертации составляет 106 страниц, включая 59 рисунков и 4 таблицы. Список литературы содержит 59 наименований.

Глава 1. Обзор существующих технологий бинарной трансляции

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

В разделе 1.1 приводится описание методов оптимизаций приложений.

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

В разделе 1.3 подробно рассматривается устройство бинарного оптимизатора BOLT (Binary Optimization and Layout Tool), вопросы получения профильной информации для его работы на х86 архитектуре с использованием аппаратной поддержки профилирования - LBR (Last Branch Record).

Разбираются вопросы формата профилей с информацией о взятых переходах и без неё и пример оптимизации простого приложения с условным переходом в цикле.

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

1.1 Процесс оптимизации приложений

На данный момент большинство программ пишутся на языке программирования высокого уровня, после чего применяются трансляторы, переводящие их в бинарный формат (рисунок 1.1). Так называемые программирующие программы (компиляторы) появились ещё в 50-х годах двадцатого века.

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

Рисунок 1.1 Варианты работы транслятора

языков применяются дополнительные оптимизации времени компоновки кода (LTO Link Time Optimizations), поскольку на этом этапе становится доступно больше информации о всех полученных объектных файлах. После компоновки кода приложение готово к использованию [1]. Для данных оптимизаций использовалась информация о приложении, полученная из исходного кода.

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

1.2 Бинарная оптимизация

В случае, когда доступа к исходному коду нет, но есть бинарный файл приложения и его профиль исполнения, появляется возможность провести бинарную оптимизацию[3]. Тогда на вход транслятору будет подаваться не языковой, а бинарный файл (рисунок 1.1), который будет переведён в другой бинарный формат.

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

За последние несколько лет наблюдается резкий рост популярности бинарных оптимизаторов: BOLT [4], Propeller [5], Janus [6], HALO [7], Ispike [8]. Эти

и

инструменты используют профильную информацию исполнения для принятия решений по оптимизации.

Оптимизация, основанная на обратной связи (FDO, Feedback Directed Optimization), является эффективным методом повышения производительности программ сверх того, что обычно могут достичь статические компиляторы [9]. В данном сценарии компилятор использует информацию, полученную в результате предыдущих исполнений целевой программы, для выполнения более агрессивных преобразований кода. FDO является ключевым компонентом инструментов бинарной оптимизации, которые полагаются на информацию профилирования для выполнения преобразований, таких как изменение порядка базовых блоков и функций. Эти инструменты достигают прироста производительности благодаря оптимизации с профилем исполнения: BOLT (Binary Optimization and Layout Tool) [4] дает ускорение приложений до 30% (при отсутствии предварительных профильных оптимизаций).

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

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

1.3 Обзор бинарного оптимизатора BOLT

Основными целевыми приложениями для оптимизатора BOLT являются современные программы для центров обработки данных. Из-за размера кода программ повышение его локализации стало важным инструментом повышения производительности [10]. Основной оптимизацией BOLT является перекомпоновка кода на основе полученного профиля, использование которого на бинарном уровне точнее, чем на этапе компиляции (рисунок 1.2) [11]. Создатели данного бинарного оптимизатора достигли прироста производитель-

ыости в 10% на х86 приложениях, скомпилированные с оптимизациями времени связывания и с использованием профиля [4] [12].

.text

Оригинальный код

.bolt. org. text .text .text, с о Id

Опциональная копня Горячий код Холодный код

Рисунок 1.2 Алгоритм работы бинарного оптимизатора BOLT

Данный бинарный оптимизатор написан с использованием фреймворка генерации компиляторов LLVM [13], что делает BOLT потенциально портиру-емым на множество других архитектур. Базовая поддержка ARM архитектуры (Aarch64) на данный момент уже добавлена.

BOLT применим к приложениям, размер которых значительно больше размера L1I (инструкционного кэша 1 уровня) и размера отображаемого кода iTLB (буфер ассоциативной трансляции инструкций) - десятки мегабайт и более. За счет новой компоновки кода, основанной на профиле, часто исполняемый код локализуется в новой секции. Частоту исполнения кода называют его «температурой», и в данном примере созданная секция является «горячей». Остальной же код с меньшей частотой исполнения будет называться «холодным». Теперь при обращении в горячий участок кода в кэш-линию, помимо исполняемого в данный момент кода, будут попадать более горячие соседние участки из новой секции, и температура кода инструкционного кэша будет выше [14]. Это приводит к меньшим промахам при обращении в L1I и iTLB, а значит к повышению производительности.

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

фон-Неймановских архитектур: код и данные располагаются в одном адресном пространстве.

На рисунке 1.3 представлен пример, когда одни и те же 4-байтовые данные могут обозначать либо ARM инструкцию условного перехода, либо 4 символа. При перекомпоновке необходимо изменить значение смещения инструкции b.ls, во втором случае 4-байтовые данные должны остаться неизменными, поэтому без дополнительной информации о расположении данных оптимизатор не сможет решить, как обработать секцию корректно.

Туре CODE DATA

HEX 0x29542854 0x29542854

Decode b.ls Ox50A84 "(T)T"

New decode b.ls 0x4004 "(T)T"

New HEX 0x29000254 0x29542854

Рисунок 1.3 Пример модификации 4-байтовых данных при перемещении кода

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

1.3.1 Получение профильной информации для оптимизатора

BOLT

Один из способов собрать профиль провести инструментацию бинарного файла [15]. Во время запуска будет произведена запись по счетчикам, расставленным во время компиляции, но для данного подхода необходим исходный код. Основная проблема заключается в необходимости адаптации инфраструктуры сборки проекта для профилирования. Кроме того, используемые сторонние

библиотеки не предоставляются в инструментированном виде, что осложняет получения полной картины исполнения [16].

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

При наличии архитектурной поддержки есть возможность собрать информацию исполнения с меньшими расходами. В х86 архитектуре такая поддержка есть, что позволило сотрудникам Facebook использовать такой подход в своём бинарном оптимизаторе BOLT (рисунок 1.4) [4].

Рисунок 1.4 Схема оптимизации бинарного файла на х86 архитектуре

Для нахождения горячих и холодных участков кода используется профиль (рисунок 1.5), собранный на основе выборок. BOLT использует данные,

полученные с помощью приложения perf, собирающее статистические данные исполнения, такие как значения счетчика команд и последние взятые переходы с информацией от предсказателя переходов. Последний параметр предоставляется perf благодаря аппаратной поддержке в архитектуре х86. Поддержка осуществляется с помощью LBR (Last Branch Record), записывающей информацию о последних 8-32 (в зависимости от модели процессора) переходах.

Source Destination Mispredict Taken

1 main Ь9 1 trueFunc 0 0 20

1 main а8 1 main eO 21 78

Рисунок 1.5 Формат профильной информации бинарного оптимизатора

BOLT

Сначала идет информация о местонахождении инструкции перехода (Source). Это поле задается тремя значениями: является ли дальнейшее поле символом (0 или 1), имя символа в исполняемом файле, смещение от символа до инструкции перехода. Далее в такой же последовательности следует информация о месте назначения прыжка (Destination). Последние два числа количество не предсказанных и количество взятых переходов. На рисунке 1.5 продемонстрирована информация о двух переходах:

1. Вызов trueFunc из main, являющийся прямым прыжком (поэтому mispredict — 0), взятый 20 раз.

2. Переход внутри функции main, который является условным прыжком, не предсказанный 21 раз и взятый 78 раз.

Затем происходит конвертация профиля из формата perf в формат BOLT при помощи приложения perf2bolt. В итоге будет сгенерирован список записей, состоящих из адресов начала и конца перехода, количества не предсказанных и количества взятых переходов.

На основании полученного профиля начинается работа бинарного оптимизатора. На рисунке 1.6 представлена схема работы BOLT.

Уровни абстракций, на которых работает BOLT, выстраиваются в последовательности, показанной на рисунке 1.7.

Рисунок 1.6 Последовательность работы бинарного оптимизатора BOLT

Рисунок 1.7 Уровни абстракции бинарного оптимизатора BOLT

Для первых 4 абстракций создатели BOLT написали в программном коде свои собственные классы. Машинные инструкции были использованы из стандартных классов LLVM (MCInst). Под бинарным базовым блоком понимается линейный участок кода, исполнение которого всегда идёт с его первой инструкции и заканчивается последней.

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

BOLT поддерживает возможность сохранения оригинальной секции. В таком случае он переименует её в .bolt.org.text. Это необходимо для тех случаев, когда перенос некоторых бинарных функций невозможен и необходимо переиспользовать оригинальный код.

1.3.2 Пример оптимизации

Рассмотрим пример оптимизации следующей функции main (рисунок 1.8).

BOLT найдёт символ main в таблице символов, перейдёт по указанному адресу в бинарном файле, дезассемблирует тело функции и выстроит поток управления данной функции (рисунок 1.9).

Каждому узлу в графе потока управления соответствует один бинарный базовый блок, которым будет оперировать BOLT. При компиляции без профильной информации компилятор размещает код последовательно в одной .text секции, как указано на рисунке 1.11 слева. После запуска программы с профи-

l. 2,

3,

4,

5,

6,

7.

8, 9,

10. 11, 12.

13,

14,

15,

16,

17,

18.

19,

20,

int mainfint argc, char** argv) {

if (argc != 3) {

printf ( "Weed two argunients\ii" ) ; return 1;

}

double res = 0.0;

uint32_t TRUE = 0, FALSE = 0; uint32_t arg = atoi (argv[1]); uint32_t itNuinber = atoi (argv[2]); for ( uint32 t i — 1; i < itNuinber; i+ + ) { if (condition(i, arg)) {

res += trueFunc(i, &TRUE); } else {

res += falseFunc(i, &FALSE};

}

}

print.f (" [T : %d | F: %d] %lf\n", TRUE, FALSE, res); return 0;

Рисунок 1.8 Пример оптимизируемого демонстрационного приложения

лировщиком на конкретных аргументах получим следующий профиль (рисунок 1.10).

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

Оптимизация BOLT переставляет бинарные базовые блоки (рисунок 1.11, справа). Самые горячие блоки попадут в горячую секцию .text, остальные будут скопированы в секцию .text.cold. В итоге за счёт повышения средней температуры L1I и iTLB полученный бинарный файл будет работать быстрее.

Как было сказано раньше, основной архитектурой для оптимизации была заявлена х86. Также заявлена поддержка 64-битной ARM архитектуры (Aarch64), но наделе возникает множество проблем при попытке использования оптимизатора на ней. Они будут рассмотрены в следующих разделах.

Check Args (3}

Рисунок 1.9 Граф потока управления (в скобках соответствующие строки

кода)

1.3.3 Результаты тестирования ВОЬТ на архитектуре х86

Для приведенного кода (рисунок 1.8) был получен профиль на х86 архитектуре с (таблица 1) и без (таблица 2) информацией о взятых переходах из ЫШ.

по_ЬВЯ_тос1е режим сбора статистики без ЬВЯ, в котором профильная информация включает в себя только количество исполнений конкретных инструкций.

На данном приложении удалось получить 10% прирост производительности на х86 архитектуре. Прирост производительности без информации из ЬВЯ был в два раза ниже.

Рисунок 1.10 Граф потока управления с профильной информацией

Рисунок 1.11 Расположение базовых блоков в секции (без профильной информации с профильной информацией после перекомпоновки кода)

Таблица 1 — Профиль демонстрационного примера на х86 архитектуре, собранного с учетом информации из ЬВИ

1 main 75 1 main 7b 0 452

1 main 9e 1 main a4 0 421

1 main ec 1 main fl 0 331

1 main e2 1 falseFunc 0 0 665

1 main c8 1 main fl 0 98

1 main 9e 1 main cd 317 730

1 main b9 1 trueFunc 0 0 159

1 main fl 1 main f6 0 494

1 main 96 1 condition 0 0 4535

1 main ff 1 main 6e 0 490

1 main 8c 1 atoi@PLT 0 0 468

0 unknown 0 1 main 91 0 4346

1 falseFunc le 1 falseFunc 25 0 569

1 falseFunc 2b 1 falseFunc 31 0 2558

1 falseFunc 2b 1 falseFunc 5f 303 378

1 falseFunc 5a 1 falseFunc 25 0 2657

1 falseFunc 65 1 main e7 0 372

1 condition 7b 1 main 9b 1 891

1 condition 38 1 sin@PLT 0 0 4695

0 unknown 0 1 condition 3d 1 1528

1 sin@PLT 0 0 unknown 0 34 4826

1 trueFunc le 1 trueFunc 25 0 147

1 trueFunc 2b 1 trueFunc 31 0 656

1 trueFunc 2b 1 trueFunc 5f 83 105

1 trueFunc 65 1 main be 0 102

1 trueFunc 5a 1 trueFunc 25 0 678

1 atoi@PLT 0 0 unknown 0 9 541

1.3.4 Поддержка ARM архитектуры бинарным оптимизатором

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

будет недостаточно для полноценного получения прироста производительности с помощью оптимизатора [4].

Для ARMv8 есть расширения для серверных процессоров, которые близки по функциональности к LBR, но отсутствуют на других, например, на мобильных процессорах. Также в ARM архитектуре предусмотрен ЕТМ (ARM Embedded Trace Macrocell), позволяющий собрать нужную для профиля информацию, но его использование в пользовательском режиме не представляется возможным. Поэтому предлагается иной подход к сбору профильной информации [18].

Альтернативный способ получения профиля (no_LBR_mode) - это сбор значений программного счетчика (таблица 3). С их помощью собирается информация о частоте исполнения кода в процессе исполнения. Однако, такой подход не позволяет использовать весь список оптимизаций, включенных в BOLT. Данный способ применяется аналогично с использованием инструмента perf.

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

Таблица 2 — Профиль демонстрационного примера на х86 архитектуре, собранного без учета

инс зормации от ЬВИ

1 тат ЬЗ 2 1 тат ае 4

1 тат 75 1 1 тат бе 13

1 таш а9 3 1 тат 7е 5

1 тат 7Ь 1 1 тат ее 34

1 тат 89 1 1 тат е2 12

1 тат с!с 1 1 тат аэ 47

1 тат сЗ 3 1 тат 8с 6

1 тат £1 4 1 тат е7 7

1 тат Е И 1 тат Ье 1

1 тат £6 9 1 тат 82 14

1 тат ЬО 9 1 тат са 15

1 тат ао 8 1 сопс!Шоп 33 И

1 сопс!Шоп 7Ь 16 1 сопс!Шоп 47 4

1 сопс!Шоп 8 1 1 сопс!Шоп ба 136

1 сопс!Шоп 70 38 1 сопс!Шоп 73 22

1 сопс!Шоп 5е 49 1 сопс!Шоп 0 И

1 сопс!Шоп 2Ь 6 1 сопс!Шоп 4с 9

1 сопс!Шоп за 10 1 сопс!Шоп 26 14

1 сопс!Шоп 1Ь 20 1 сопс!Шоп 63 18

1 сопс!Шоп 4 14 1 сопс!Шоп 55 406

1 ГакеРипс £ 7 1 ГакеРипс 16 10

1 ГакеРипс 19 1 1 ГакеРипс 51 20

1 ГакеРипс Зс 25 1 ГакеРипс 4с 85

1 ГакеРипс 25 34 1 ГакеРипс 4 9

1 ГакеРипс 5а 6 1 ГакеРипс 57 6

1 ГакеРипс 43 22 1 ГакеРипс Зе 14

1 ГакеРипс 1 1 1 ГакеРипс 64 12

1 ГакеРипс 54 4 1 ГакеРипс 39 9

Похожие диссертационные работы по специальности «Математическое и программное обеспечение вычислительных машин, комплексов и компьютерных сетей», 05.13.11 шифр ВАК

Список литературы диссертационного исследования кандидат наук Лисицын Сергей Алексеевич, 2022 год

Список литературы

1. Wu, Y. Static branch frequency and program profile analysis [Текст] / Y. Wu, J. R. Larus // Professional Engineering. — 1994. T. 7. Л'0 21.

2. bicker, N. Duplo: A framework for OCaml post-link optimisation [Текст] / N. Licker, T. M. Jones // Proceedings of the ACM on Programming Languages. - 2020. - T. 4, ICFP.

3. Li, G. Accelerating GPU Computing at Runtime with Binary Optimization [Текст] / G. Li, L. Liu, X. Feng // CGO 2019 - Proceedings of the 2019 IEEE/ACM International Symposium on Code Generation and Optimization. — 2019.

4. BOLT: A Practical Binary Optimizer for Data Centers and beyond [Текст] / M. Panchenko [и др.] // CGO 2019 - Proceedings of the 2019 IEEE/ACM International Symposium on Code Generation and Optimization. — 2019.

5. Moreira, A. A. VESPA: Static profiling for binary optimization [Текст] / A. A. Moreira, G. Ottoni, F. M. Quintâo Pereira // Proceedings of the ACM on Programming Languages. — 2021. — T. 5, OOPSLA.

6. Zhou, R. Janus: Statically-Driven and Profile-Guided Automatic Dynamic Binary Parallelisation [Текст] / R. Zhou, T. M. Jones // CGO 2019 -Proceedings of the 2019 IEEE/ACM International Symposium on Code Generation and Optimization. — 2019.

7. Savage, J. HALO: Post-link heap-layout optimisation [Текст] / J. Savage, T. M. Jones // CGO 2020 - Proceedings of the 18th ACM/IEEE International Symposium on Code Generation and Optimization. — 2020.

8. Ispike: A post-link optimizer for the Intel@Itanium(R) architecture [Текст] / С. К. Luk [и др.] // International Symposium on Code Generation and Optimization, CGO. - 2004.

9. Chen, D. AutoFDO: Automatic feedback-directed optimization for warehouse-scale applications [Текст] / D. Chen, D. X. Li, T. Moseley // Proceedings of the 14th International Symposium on Code Generation and Optimization, CGO 2016. - 2016.

10. Ottoni, G. Optimizing function placement for large-scale data-center applications [Текст] / G. Ottoni, B. Maher // CGO 2017 - Proceedings of the 2017 International Symposium on Code Generation and Optimization. — 2017.

11. Newell, A. Improved Basic Block Reordering [Текст] / A. Newell, S. Pupyrev // IEEE Transactions on Computers. - 2020. - T. 69, № 12.

12. Lightning BOLT: Powerful, fast, and scalable binary optimization [Текст] / M. Panchenko [и др.] // CC 2021 - Proceedings of the 30th ACM SIGPLAN International Conference on Compiler Construction. — 2021.

13. Lattner, C. LLVM: A compilation framework for lifelong program analysis & transformation [Текст] / С. Lattner, V. Adve // International Symposium on Code Generation and Optimization, CGO. — 2004.

14. Lavaee, R. Codestitcher: Inter-procedural basic block layout optimization [Текст] / R. Lavaee, J. Criswell, C. Ding // ACM International Conference Proceeding Series. — 2019.

15. Ottoni, G. HHVM JIT: a profile-guided, region-based compiler for PHP and Hack [Текст] / G. Ottoni // ACM SIGPLAN Notices. - 2018. - T. 53, № 4.

16. Nethercote, N. Valgrind: A framework for heavyweight dynamic binary instrumentation [Текст] / N. Nethercote, J. Seward // ACM SIGPLAN Notices. - 2007. - T. 42, № 6.

17. Li, J. Dynamic binary translation and optimization [Текст] / J. Li, X. Ma,

C. Zhu // Jisuanji Yanjiu yu Fazhan/Computer Research and Development. — 2007. - T. 44, № 1.

18. Work-in-Progress: Exploiting SIMD Capability in an ARMv7-to-ARMv8 Dynamic Binary Translator [Текст] / S. Y. Fu [и др.] // 2018 International Conference on Compilers, Architecture and Synthesis for Embedded Systems, CASES 2018. - 2018.

19. Nethercote, N. Valgrind: A program supervision framework [Текст] / N. Nethercote, J. Seward // Electronic Notes in Theoretical Computer Science. T. 89. - 2003.

20. Bruening, D. An infrastructure for adaptive dynamic optimization [Текст] /

D. Bruening, T. Garnett, S. Amarasinghe // International Symposium on Code Generation and Optimization, CGO 2003. — 2003.

21. Rimsa, Л. Efficient and precise dynamic construction of control flow graphs [Текст] / A. Rimsa, J. N. Amaral, F. M. Quintao // ACM International Conference Proceeding Series. — 2019.

22. Hazelwood, K. Managing Bounded Code Caches in Dynamic Binary Optimization Systems [Текст] / К. Hazelwood, M. D. Smith // ACM Transactions on Architecture and Code Optimization. — 2006. Т. 3. A'0 3.

23. Processor-tracing guided region formation in dynamic binary translation [Текст] / D. Y. Hong [и др.] // ACM Transactions on Architecture and Code Optimization. - 2019. - T. 15, № 4.

24. Лисицын, С. А. Сбор профильной информации с помощью трасс исполнения приложения для статической оптимизирующей бинарной трансляции [Текст] / С. А. Лисицын // Международный научный журнал «Современные информационные технологии и ИТ-образование». - 2021. - Т. 17, № 2. - С. 369 378.

25. Лисицын, С. А. Сбор профильной информации с помощью трасс исполнения приложения для статической оптимизирующей бинарной трансляции [Текст] / С. А. Лисицын // Программа международного конгресса «Современные проблемы компьютерных и информационных наук». — 2021.

26. A Probabilistic Monte Carlo Framework for Branch Prediction [Текст] / В. Kalla [и др.] // Proceedings - IEEE International Conference on Cluster Computing, ICCC. 2017^Septe. - 2017.

27. Ball, T. Branch prediction for free [Текст] / Т. Ball, J. R. Larus //. — 1993.

28. Fisher, J. A. Predicting conditional branch directions from previous runs of a program [Текст] / J. A. Fisher, S. M. Freudenberger // International Conference on Architectural Support for Programming Languages and Operating Systems - ASPLOS. T. 27. - 1992.

29. Smith, J. E. A study of branch prediction strategies [Текст] / J. E. Smith // Proceedings - International Symposium on Computer Architecture. — 1981.

30. Exploring predictive replacement policies for instruction cache and branch target buffer [Текст] / S. M. Ajorpaz [и др.] // Proceedings - International Symposium on Computer Architecture. — 2018.

31. Blem, E. Power struggles: Revisiting the RISC vs. CISC debate on contemporary ARM and x86 architectures [Текст] / E. Blem, J. Menon, K. Sankaralingam // Proceedings - International Symposium on HighPerformance Computer Architecture. — 2013.

32. Лисицын, С. А. Изучение проблем статической двоичной трансляции под RISC архитектуры [Текст] / С. А. Лисицын // ТРУДЫ 63-й Всероссийской научной конференции МФТИ. Радиотехника и компьютерные технологии. — 2020.

33. Computational overhead of locality reduction in binary optimization problems [Текст] / E. Valiante [и др.] // Computer Physics Communications. — 2021. — T. 269.

34. Lin, Y. Control-flow integrity enforcement with dynamic code optimization [Текст] / Y. Lin // Information Security and Cryptography. — 2021.

35. Rimsa, A. Practical dynamic reconstruction of control flow graphs [Текст] / A. Rimsa, J. Nelson Amaral, F. M. Pereira // Software - Practice and Experience. - 2021. - T. 51, № 2.

36. Лисицын, С. А. Верификация статической двоичной оптимизирующей трансляции под RISC архитектуры [Текст] / С. А. Лисицын, А. А. Шуры гин // ТРУДЫ 64-й Всероссийской научной конференции МФТИ. Радиотехника и компьютерные технологии. — 2021.

37. Vandeputte, F. Exploiting program phase behavior for energy reduction on multi-configuration processors [Текст] / F. Vandeputte, L. Eeckhout, K. De Bosschere // Journal of Systems Architecture. — 2007. — T. 53, № 8.

38. Control flow integrity enforcement with dynamic code optimization [Текст] / Y. Lin [и др.] // Lecture Notes in Computer Science (including subseries Lecture Notes in Artificial Intelligence and Lecture Notes in Bioinformatics). 9866 LNCS. - 2016.

39. Lebras, Y. Combining static and dynamic analysis to guide PGO for HPC applications: A case study on real-world applications [Текст] / Y. Lebras, A. S. Charif-Rubial, W. Jalby // 2019 International Conference on High Performance Computing and Simulation, HPCS 2019. — 2019.

40. Desmond, M. An evaluation of the inline source code exploration technique [Текст] / M. Desmond, C. Exton // Ppigorg. — 2009.

41. Лисицын, С. А. Мультипрофильная статическая бинарная оптимизация приложения на основе трасс исполнения [Текст] / С. А. Лисицын // Международный научный журнал «Современные информационные технологии и ИТ-образование». - 2021. - Т. 17, № 3. - С. 500 579.

42. SOCRATES - A seamless online compiler and system runtime autotuning framework for energy-aware applications [Текст] / D. Gadioli [и др.] // Proceedings of the 2018 Design, Automation and Test in Europe Conference and Exhibition, DATE 2018. 2018^Janua. - 2018.

43. Desmet, V. Using decision trees to improve program-based and profile-based static branch prediction [Текст] / V. Desmet, L. Eeckhout, K. De Bosschere // Lecture Notes in Computer Science (including subseries Lecture Notes in Artificial Intelligence and Lecture Notes in Bioinformatics). 3740 LNCS. — 2005.

44. A survey on compiler autotuning using machine learning [Текст] / A. H. Ashouri [и др.]. — 2018.

45. Ripple: Profile-guided instruction cache replacement for data center applications [Текст] / Т. A. Khan [и др.] // Proceedings - International Symposium on Computer Architecture. 2021^June. — 2021.

46. Bruening, D. Efficient, transparent, and comprehensive runtime code manipulation [Текст] / D. Bruening // Electrical Engineering. — 2004.

47. Neves, N. Compiler-Assisted Data Streaming for Regular Code Structures [Текст] / N. Neves, P. Tomas, N. Roma // IEEE Transactions on Computers. — 2021. - T. 70, № 3.

48. O'Dea, S. Global smartphone sales to end users 2007-2021 [Текст] / S. O'Dea. - 2020.

49. Binary Optimization Using Hybrid Grey Wolf Optimization for Feature Selection [Текст] / Q. Al-Tashi [и др.] // IEEE Access. - 2019. - T. 7.

50. Pereira, F. M. Q. Static prediction of silent stores [Текст] / F. M. Q. Pereira, G. V. Leobas, A. Gamatie // ACM Transactions on Architecture and Code Optimization. - 2019. - T. 15, № 4.

51. Ottoni, G. HHVM Jump-Start: Boosting Both Warmup and Steady-State Performance at Scale [Текст] / G. Ottoni, B. Liu // CGO 2021 - Proceedings of the 2021 IEEE/ACM International Symposium on Code Generation and Optimization. — 2021.

52. Sari, A. A Highly Scalable Instruction Scheduler Design based on CPU Stall Elimination [Текст] / A. Sari, I. Butun // 2021 Zooming Innovation in Consumer Technologies Conference, ZINC 2021. — 2021.

53. Li, D. X. Lightweight feedback-directed cross-module optimization [Текст] / D. X. Li, R. Ashok, R. Hundt // Proceedings of the 2010 CGO - The 8th International Symposium on Code Generation and Optimization. — 2010.

54. Cinnamon: A Domain-Specific Language for Binary Profiling and Monitoring [Текст] / M. Arif [и др.] // CGO 2021 - Proceedings of the 2021 IEEE/ACM International Symposium on Code Generation and Optimization. — 2021.

55. GPA: A GPU Performance Advisor Based on Instruction Sampling [Текст] / К. Zhou [и др.] // CGO 2021 - Proceedings of the 2021 IEEE/ACM International Symposium on Code Generation and Optimization. — 2021.

56. Holzle, U. Optimizing dynamically-dispatched calls with run-time type feedback [Текст] / U. Holzle, D. Ungar // Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI). — 1994.

57. Ying, V. A. T4: Compiling Sequential Code for Effective Speculative Parallelization in Hardware [Текст] / V. A. Ying, M. C. Jeffrey, D. Sanchez // Proceedings - International Symposium on Computer Architecture. 2020-May. - 2020.

58. Ovasapyan, T. D. Application of Taint Analysis to Study the Safety of Software of the Internet of Things Devices Based on the ARM Architecture [Текст] / Т. D. Ovasapyan, P. V. Knyazev, D. A. Moskvin // Automatic Control and Computer Sciences. - 2020. - T. 54, № 8.

59. I-SPY: Context-driven conditional instruction prefetching with coalescing [Текст] / Т. A. Khan [и др.] // Proceedings of the Annual International Symposium on Microarchitecture, MICRO. 2020^0ctob. - 2020.

Список рисунков

1 Процесс трансляции исходного кода в оптимизированный бинарный

файл..........................................................................4

1.1 Варианты работы транслятора............................................10

1.2 Алгоритм работы бинарного оптимизатора BOLT......................12

1.3 Пример модификации 4-байтовых данных при перемещении кода . . 13

1.4 Схема оптимизации бинарного файла на х86 архитектуре ............14

1.5 Формат профильной информации бинарного оптимизатора BOLT . . 15

1.6 Последовательность работы бинарного оптимизатора BOLT..........16

1.7 Уровни абстракции бинарного оптимизатора BOLT....................16

1.8 Пример оптимизируемого демонстрационного приложения............17

1.9 Граф потока управления (в скобках соответствующие строки кода) . 18

1.10 Граф потока управления с профильной информацией..................19

1.11 Расположение базовых блоков в секции (без профильной информации - с профильной информацией - после перекомпоновки кода)..........................................................................19

2.1 Предлагаемая схема оптимизации бинарного файла на ARM архитектуре..................................................................25

2.2 Схема генерации профиля из трассы исполнения ......................26

2.3 Сравнение методов сбора профильной информации....................28

2.4 Профили, полученные с помощью трассы и LBR........................28

2.5 Граф управления синтетического теста с профильной информацией 31

2.6 Сравнение результатов запусков оригинального и оптимизированного бинарных файлов синтетического теста..........35

3.1 Сравнение инструкций, зависящих от счетчика инструкций ..........38

3.2 Пример перекомпоновки горячего кода..................................38

3.3 Генерация трамплина для инструкции условного перехода............39

3.4 Сравнение условного и безусловного перехода..........................39

3.5 Сравнение трамплинов ....................................................40

3.6 Схема добавления трамплинов для ADR (сверху) и Всс (снизу) инструкций..................................................................40

3.7 Пример ассемблерного кода для switch-case случая....................42

3.8 Заполненная структура релокацпонной записи для перехода по значению регистра..........................................................42

3.9 Преобразование смещений при перекомпоновке кода ..................43

3.10 Оптимизированный вариант ассемблерного кода для switch-case случая........................................................................44

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

3.12 Ошибочный расчет целевого адреса бинарным оптимизатором .... 45

3.13 Преобразование смещений при перекомпоновке оптимизированного кода..........................................................................45

3.14 Пример кода с переходом по значению регистра (тестовый набор GeekBench)..................................................................46

3.15 Пример кода с переходом по значению регистра после перекомпоновки (тестовый набор GeekBench)............................46

3.16 Пример файла преобразований бинарного файла ......................47

3.17 Схема верификации бинарного файла....................................47

3.18 Пример файла разрешенных преобразований............................48

3.19 Проверка линейного участка без изменения количества инструкций . 49

3.20 Проверка линейного участка с измененным количества инструкций . 49

3.21 Результаты исполнения оригинального Clang теста....................50

3.22 Результаты исполнения оптимизированного Clang теста................51

4.1 Граф потока управления с профилем....................................53

4.2 Граф потока управления с измененным профилем......................54

4.3 Граф потока управления с суммарным профилем......................54

4.4 Оптимизированная секция с дублированием кода......................55

4.5 Поток управления по секции с дублированием кода....................56

4.6 Варианты оптимизированных секций....................................57

4.7 Построение тепловой карты линейных участков........................58

4.8 Добавление фаз исполнения в тепловую карту (верхняя строка тепловой карты)............................................................59

4.9 Тепловая карта приложения, запущенного в трех разных режимах . 60

4.10 Граф потока управления по фазам ......................................60

4.11 Соответствие графа потока управления по фазам со сценариями . . 61

4.12 Пример построения соответствия линейных участков фазам..........61

4.13 Пример тепловой карты приложения до сортировки....................62

4.14 Пример тепловой карты приложения после сортировки................63

4.15 Пример тепловой карты для реальной библиотеки приложения ... 63

4.16 Дублирование кода на основе мультипрофиля..........................64

4.17 Тепловая карта набора тестов СеекЬепсЬ с выделенными тестами . . 65

4.18 Сравнение прироста производительности................................66

4.19 Результаты тестирования мультипрофильного дублирования кода . . 66

Список таблиц

1 Профиль демонстрационного примера на х86 архитектуре, собранного с учетом информации из LBR................ 20

2 Профиль демонстрационного примера на х86 архитектуре, собранного без учета информации от LBR............... 22

3 Профиль демонстрационного примера на ARM архитектуре, собранного в режиме no LBR....................... 23

4 Профиль демонстрационного примера на ARM архитектуре, собранный с трассы исполнения приложения.............. 30

Приложение А Программный код основных синтетических тестов

В данном приложении приводится исходный код трёх основных синтетических тестов, которые использовались для проверки бинарного оптимизатора BOLT. Основным методом получения большого размера бинарного файла (> 10 МБ) было использование рекурсивных шаблонов. С их помощью компилятор создавал множественные копии функций с разными шаблонными константами, тем самым увеличивая размер кода до нужного значения.

Листинг А.1 Синтетический тест без стандартной библиотеки

// BUILD FOR ARM: aarch64 - linux - androi d - cl ang+ + start_ARM.S start. cpp -nostdlib -00 -std-c++ll -Wl,-q -pie -ftemplate-depth-1000000 -o ARM_nostdlib -D CSIZE^IOOO -D CSTEP^IO // BUILD FOR X86: g+ + start_x86.S start, cpp -nostdlib -00 -std^c + + 11 -ftemplate-depth^lOOOOOO -o x86_nostdlib -D CSIZE^IOOO -D CSTEP-10

#define UINT_MAX 4294967295

template<unsigned int param>

double falseFunc(unsigned int i, unsigned int* FALSE) {

if (i == UINT_MAX) {

falseFunc<param-l>(i, FALSE);

>

(* FALSE)++;

return 1.0/С i + param) ;

>

template <>

double falseFunc<0>(unsigned int i, unsigned int* FALSE) {

(* FALSE)++; return 1.0/(i + 1) ;

>

template<unsigned int param>

double trueFunc(unsigned int i, unsigned int* TRUE)

30

35

40

45

50

55

60

if (i == UINT_MAX) {

trueFunc<param-1>(i , TRUE);

>

(* TRUE)++;

return 2.0/(i + param);

>

template <>

double trueFunc<0>(unsigned int i, unsigned int* TRUE) {

(* TRUE)++;

return 2.0/(i + 1) ;

// values from 0 to 2 // 0 - always true // 2 - always false template<unsigned int param>

unsigned int condition(unsigned int i, unsigned int arg) // 0-2 {

if (i == UINT_MAX) {

condition<param-l>(i, arg);

>

double val = 1 + ((i*i + param) 2); // 1-2 return val > arg;

>

template <>

unsigned int condition<0>(unsigned int i, unsigned int arg) {

double val = 1 + ((i*i) I 2) ; return val > arg;

>

template<unsigned int param>

double calcFunc(unsigned int calc_args) {

double res = 0.0;

unsigned int TRUE = 0, FALSE = 0; unsigned int arg = param °/0 3; unsigned int itNumber = calc_args;

75

80

85

90

95

100

105

if (itNumber == UINT_MAX) {

calcFunc<param-1>(calc_args) ;

>

for (unsigned int i = 1; i <= itNumber; i++) {

if ( condit ion <param > ( i , arg)) {

res += trueFunc<param>(i, &TRUE) ; } else {

res += falseFunc<param> (i , &FALSE) ;

>

return res ;

>

template <>

double calcFunc<0>(unsigned int calc_args) {

double res = 0.0;

unsigned int TRUE = 0, FALSE = 0;

unsigned int arg = 0;

unsigned int itNumber = calc_args;

for (unsigned int i = 1; i <= itNumber; i++) {

if ( condit ion <0 >( i , arg)) {

res += trueFunc<0>(i , &TRUE) ; } else {

res += f alseFunc <0>(i , &FALSE) ;

>

>

return res ;

# ifndef CSIZE

#define CSIZE 1000

# endif

const uint32_t C0DE_SIZE = CSIZE;

# ifndef CSTEP

#define CSTEP 10

}

120

125

130

135

# endif

const uint32_t C0DE_STEP = CSTEP;

template<unsigned int param>

double hotFunc(unsigned int calc_args) {

return calcFunc<param>(calc_args) + hotFunc<param CODE_STEP>(calc_args);

>

template <>

double hotFunc<0>(unsigned int calc_args) {

return calcFunc<0>(calc_args);

>

int main()

unsigned int hot_repeat = 100000; calcFunc<C0DE_SIZE> (1) ;

for (unsigned int i = 0; i < hot_repeat; i++) {

hotFunc<C0DE_SIZE>(l);

>

return 0;

Листинг A.2 Стартовый ассемблерный код для ARM архитектуры для теста без стандартной библиотеки .globl _start

_start: bl main mov xO, #42 mov x8, #93 svc #0x0

Листинг А.З Стартовый ассемблерный код для х86 архитектуры для теста без стандартной библиотеки .globl _start

_start

call main movl $1 , °/0eax xorl °/0ebx , °/0ebx int $0x80

Листинг A.4 Синтетический тест с использованием стандартной библиотеки

// BUILD FOR ARM: aarch64-linux-android-g + + main. cpp -00 -std-c + + 11 -Wl,-q -pie -ftemplate -depth^lOOOOOO -o main_ARM64 -D CSIZE-1000 -D CSTEP-10 // BUILD FOR X86: g++ main. cpp -00 -std^c++ll -Ipthread -

ftemplate -depth^lOOOOOO -o main_x86 -D CSIZE^IOOO -D CSTEP^IO #include <cstdio> #include <cstdlib> #include <cstdint> #include <pthread.h> #include <unistd.h> #include <limits>

template<uint32_t param>

double falseFunc(uint32_t i, uint32_t* FALSE)

if (i == std::numeric_limits<uint32_t>::max()) { falseFunc<param-1>(i , FALSE);

>

(* FALSE)++;

return 1.0/С i + param) ;

>

20 template <>

double falseFunc<0>(uint32_t i, uint32_t* FALSE)

(* FALSE)++; return 1.0/(i + 1) ;

template<uint32_t param>

double trueFunc(uint32_t i, uint32_t* TRUE)

if (i == std::numeric_limits<uint32_t>::max()) { trueFunc<param-1>(i , TRUE);

>

(* TRUE)++;

return 2.0/(i + param);

10

15

40

45

50

55

60

65

70

template <>

double trueFunc<0>(uint32_t i, uint32_t* TRUE)

(* TRUE)++;

return 2.0/(i + 1) ;

// values from 0 to 2 // 0 - always true // 2 - always false template<uint32_t param>

uint32_t condition(uint32_t i, uint32_t arg) // 0-2 {

if (i == std::numeric_limits<uint32_t>::max()) { condition<param-l>(i, arg);

>

double val = 1 + ((i*i + param) 2); // 1-2 return val > arg;

>

template <>

uint32_t condition<0>(uint32_t i, uint32_t arg) {

double val = 1 + ((i*i) I 2) ; return val > arg;

>

template<uint32_t param>

void *calcFunc(void *calc_args) {

char** argv = (char**) calc_args;

double res = 0.0;

uint 32_t TRUE = 0, FALSE = 0;

uint32_t arg = (atoi (argv [1]) + param) °/0 3;

uint32_t itMumber = atoi(argv [2]) ;

if (itMumber == std::numeric_limits<uint32_t> : :max ()) { calcFunc<param-1>(calc_args);

>

for (uint32_t i = 1; i <= itMumber; i++)

85

90

95

100

105

110

115

if ( condit ion <param > ( i , arg) ) {

res += trueFunc<param>(i, &TRUE) ; } else {

res += falseFunc<param> (i , &FALSE) ;

>

return nullptr ;

>

template <>

void *calcFunc<0>(void *calc_args) {

char** argv = (char**) calc_args;

double res = 0.0;

uint 32_t TRUE = 0, FALSE = 0;

uint32_t arg = (atoi (argv [1]) ) 3;

uint32_t itMumber = atoi(argv [2]) ;

for (uint32_t i = 1; i <= itMumber; i++) {

if ( condit ion <0 >( i , arg)) {

res += trueFunc<0>(i , &TRUE) ; } else {

res += f alseFunc <0>(i , &FALSE) ;

>

>

return nullptr ;

>

# ifndef CSIZE

#define CSIZE 1000

# endif

const uint32_t C0DE_SIZE = CSIZE;

# ifndef CSTEP

#define CSTEP 10

# endif

const uint32_t C0DE_STEP = CSTEP; template<uint32_t param>

130

135

140

145

150

void *hotFunc(void *calc_args) {

calcFunc<param>(calc_args);

hotFunc<param - C0DE_STEP>(calc_args);

return nullptr;

>

template <>

void *hotFunc<0>(void *calc_args) {

calcFunc<0>(calc_args) ; return nullptr;

>

int main(int argc , char* argv []) {

if (argc != 4) {

printf("ERROR! Meed three arguments - barrier [0..10] iterations number and hot repetitions\n11) ;

printf(" 0 - always true\n 1 - 50/50\n 2 - always f alse\n") ;

return 1;

>

uint32_t hot_repeat = atoi(argv[3]); calcFunc<C0DE_SIZE>(argv) ;

for (uint32_t i = 0; i < hot_repeat; i++) {

hotFunc<C0DE_SIZE>(argv);

>

printf("SUCCESS\n"); return 0;

Листинг A.5 Синтетический тест с использованием исключений и виртуальных функций

// BUILD FOR ARM: aarch64 - linux - android - g + + exception . cpp -00 -D CSIZE-1000 -D CSTEP-10 -std^c++ll -Wl,-q -pie -ftemplate-depth-1000000 -o exception_ARM64 // BUILD FOR X86: g++ exception. cpp -00 -std^c++ll -Ipthread -ftempi at e- depth-1000000 -D CSIZE^IOOO -D CSTEP^IO -o excep t i on_x86 #include <cstdio>

10

15

20

25

30

35

#include <cstdlib> #include <cstdint> #include <pthread.h> #include <unistd.h> #include <limits> #include <stdexcept>

class BaseException : std::runtime.error { public:

BaseExcept i on () : std : : runt ime.err or (11 ~-~\n11) {} virtual bool condition () {return true; }; virtual "BaseException() {};

>;

class DerivedException : public BaseException { uint32_t value_; public:

DerivedException(uint32_t val) : value_(val) , BaseException() {}

virtual bool conditionO override { return value_ != 0;

>

template<uint32_t param>

double falseFunc(uint32_t i, uint32_t* FALSE)

if (i == std::numeric_limits<uint32_t>::max()) { falseFunc<param-1>(i , FALSE);

>

return 1. 0/ ( i + param) ;

>

template <>

double falseFunc<0>(uint32_t i, uint32_t* FALSE)

throw DerivedException (0) ; return 1. 0/ ( i + 1) ;

template<uint32_t param>

double trueFunc(uint32_t i, uint32_t* TRUE)

if (i == std::numeric_limits<uint32_t>::max()) {

45

50

55

60

65

70

75

80

trueFunc<param-1>(i, TRUE);

>

return 2.0/(i + param);

>

template <>

double trueFunc<0>(uint32_t i, uint32_t* TRUE)

throw DerivedException (1) ; return 2.0/(i + 1);

// values from 0 to 2 // 0 - always true // 2 - always false template<uint32_t param>

uint32_t condition(uint32_t i, uint32_t arg) // 0-2 {

if (i == std::numeric_limits<uint32_t>::max()) { condition<param-l>(i, arg);

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