a5eaaf0d260454baa89bc573639d6e0a.ppt
- Количество слайдов: 22
Разработка сред управляемого исполнения на примере виртуальной машины Java Занятие 7 Салищев С. И.
Оптимизирующий JIT Компилятор Достоинства и недостатки Особенности систем управляемого исполнения Общая структура оптимизирующего компилятора Отличия JIT компилятора Наиболее важные оптимизации Оптимизации управляемые динамическим профилированием Динамическое профилирование
Достоинства и недостатки По сравнению с интерпретатором и шаблонным JIT компилятором n Достоинства Ускорение выполнения кода в 4 и более раз Производительность кода сопоставимая с компилируемыми языками (C, C++, Fortran, Ada) n Недостатки Затраты ресурсов на компиляцию Увеличение времени старта Затруднение отладки пользовательского кода Высокая вероятность ошибки и нарушения семантики пользовательского кода
Особенности систем управляемого исполнения Инкапсуляция n Вызов методов для доступа к данным Наследование n Цепочки вызовов Полиморфизм n Косвенные вызовы Неопределенное время жизни объектов n Выделение всех объектов в куче
Особенности систем управляемого исполнения 2 Промежуточный код (Byte Code) n Сокрытие семантики исходного кода Ленивая загрузка классов n Неполный граф вызовов во время компиляции JIT Компилятор является частью среды n n Возможность перекомпиляции при загрузке новых классов и изменении характера нагрузки Не требуется спекулятивная оптимизация Компиляция происходит параллельно с выполнением n n Требуется учитывать время компиляции За раз компилируется небольшой блок кода
Температура кода Мертвый код n Не исполняется никогда Холодный код n Исполняется редко, не оказывает влияния на скорость работы системы Теплый код n Исполняется регулярно, влияет на скорость работы системы Горячий код n Оказывает доминирующее влияние на скорость работы системы
Модель динамической перекомпиляции Загрузка кода Byte Code Интерпретация Холодный код Шаблонная компиляция Теплый код Executable Code Оптимизирующая компиляция Исполнение Executable Code Исполнение Горячий код Мертвый код Освобождение памяти
Структура оптимизирующего компилятора Source code Profiler Data Front End Lexer Parser HIR LIR Back End Low Level Optimizations Compiler Core Control Flow Analysis Code Generation Data Flow Analysis High Level Optimizations Executable Code
Структура оптимизирующего компилятора: комментарий Front End (Транслятор) n n Зависит от языка программирования высокого уровня Возможно множество трансляторов для различных языков Compiler Core (Ядро, оптимизатор) n n Универсален для широкого класса языков и аппаратных архитектур Наиболее сложен для реализации Составляет основную ценность в структуре компилятора Требует высокой гибкости взаимодействия с трансляторами и генераторами кода Back End (Генератор Кода) n n n Зависит от аппаратной платформы Возможно множество генераторов кода для различных платформ Требует тонкой подстройки под конкретную платформу
Свойства промежуточного представления высокого уровня Сохранение семантики исходного кода n n Контексты блоков и функций Типы данных Общие подвыражения Циклы в явном виде Сохранение метаданных Упрощение оптимизации Наилучший известный HIR - Граф управления (control flow graph) n n n Узлы – блоки, участки кода без переходов Дуги – переходы между блоками Возможно параллельное исполнение блоков Хранение дополнительных данных в узлах и дугах Для описания блоков используется LIR
Анализ потока управления/данных Объединение графов управления отдельных функций Построение SSA Form n SSA Form (Single Static Assignment) – каждая переменная присваивается ровно один раз Выполнение Escape analysis n Escape analysis – нахождение максимального замкнутого подграфа управления содержащего все доступы к значению
Высокоуровневые оптимизации Продвижение констант Арифметические упрощения Удаление общих подвыражений Удаление мертвого кода Скаляризация Девиртуализация Специализация и клонирование функций Подстановка функций Векторизация циклов Удаление хвостовой рекурсии Вынесение инвариантного кода из циклов Распараллеливание блоков
Свойства промежуточного представления низкого уровня Абстракция системы команд процессора n n Гибкое представление инструкций процессора Расширяемость Удобство оптимизации Сохранение информации высокого уровня Стандартный способ – трехадресный код n n трехадресный код, квад (quad, three address code (TAC)) – каждая инструкция имеет вид x: =у op z Таким образом инструкция – четверка (op, arg 0, arg 1, result) Не все инструкции задействуют все поля, например (goto, label, -, -) Дополнительные данные хранятся в метках
Низкоуровневые оптимизации Замена цепочек суперинструкциями Конвейеризация Оптимальное назначение регистров (Register Allocation) Переупорядочивание блоков Предвыборка данных и кода Применение векторных инструкций Развертывание циклов (Loop unrolling) Оптимизация прологов и эпилогов функций
Структура оптимизирующего JIT компилятора Profiler Byte Code Front End Byte Code Translator / Idiom recognizer Scheduler HIR Compiler Core Profiler Data LIR Back End Executable Code IR Cache
Отличия от обычного оптимизирующего компилятора Распознавание Идиом n n Восстановление семантики исходного кода по промежуточному коду (Byte Code) Требуется для корректного построения HIR Обычно является зависимым от компилятора языка (javac) Плохо совместим с оптимизацией промежуточного кода Кэширование промежуточного представления n n Сохранение результатов предыдущих проходов Оптимизация времени компиляции Прямое взаимодействие с профилировщиком n n n Инструментация рабочего кода Более частое обновление данных профилирования Большее значение профилирования при выборе оптимизаций Учет не только выигрыша производительности, но и времени оптимизации n Использование инкрементальных алгоритмов
Наиболее важные оптимизации Скаляризация (scalarizing) n n n Разложение массивов и объектов на локальные переменные Уменьшает затраты на выделение памяти и сборку мусора Улучшает локальность данных Девиртуализация (devirtualization) n n n Замена виртуального вызова на прямой вызов Уменьшает затраты на косвенные вызовы Необходима для подстановки Специализация и клонирование методов (specialization and cloning) n n Разделение методов по типам параметров Требуется для межпроцедурной оптимизации Подстановка (inlining) n n Подстановка тела метода вместо вызова Подстановка констант Уменьшение затрат на вызовы Улучшает локальность кода и данных
Оптимизации управляемые профилированием Защищенные оптимизации n n n Перед исполнением оптимизированного кода проверяется условие оптимизации Например тип параметров или размер массива В случае невыполнения условия выполняется неоптимизированный код Основные типы n n защищенная скаляризация Защищенная девиртуализация Защищенная специализация Защищенная подстановка
Профилирование Определение временных метрик кода n n n Время исполнения блока кода Количество попаданий в контрольную точку Вероятность попадания в контрольную точку Вероятность нахождения контрольной точки на стеке вызовов Вероятность последовательности верхних элементов стека вызовов в момент попадания в контрольную точку Вероятность значений и типов параметров при нахождении контрольной точки на стеке вызовов Методы профилирования n n Инструментация Семплирование
Инструментация Модификация кода для изменения счетчиков Является точным методом Уменьшает производительность пользовательского кода Используется в неоптимизированном коде для быстрой реакции на разогрев кода Инструментальный код часто вставляется в безопасные точки (GC Safe Point) Обычно запрос на перекомпиляцию является частью инструментального кода
Семплирование Остановка пользовательского кода в случайные моменты времени и анализ стека вызовов Почти не влияет на производительность пользовательского кода Является вероятностным методом, имеет сравнительно низкую чувствительность Для определения момента остановки может использоваться таймер или отладочное событие (переполнение счетчика инструкций, промахов кэша) Для остановки часто используются безопасные точки Используется для обнаружения горячего кода
Замена кода Ленивая замена кода n n Новый код исполняется при следующем вызове Требует сохранения предыдущей версии кода если она исполняется в момент завершения компиляции Требуется отслеживать ссылки на старую версию кода для освобождения памяти В случае глубокой подстановки может привести к существенным потерям производительности из-за невозможности заменить долго исполняемый код Замена кода на стеке n n n Версия кода заменяется в момент завершения компиляции Требует трансформации параметров на стеке в соответствие с новой версией кода Сложность реализации
a5eaaf0d260454baa89bc573639d6e0a.ppt