- •Об авторе
- •О группе редакторов
- •Предисловие
- •Введение
- •Как использовать эту книгу
- •Загрузка исходного кода CPython
- •Что в исходном коде?
- •Настройка среды разработки
- •IDE или редактор?
- •Настройка Visual Studio
- •Настройка Visual Studio Code
- •Настройка Vim
- •Выводы
- •Компиляция CPython
- •Компиляция CPython на macOS
- •Компиляция CPython на Linux
- •Установка специализированной версии
- •Знакомство с Make
- •Make-цели CPython
- •Компиляция CPython на Windows
- •Профильная оптимизация
- •Выводы
- •Грамматика и язык Python
- •Спецификация языка Python
- •Генератор парсеров
- •Повторное генерирование грамматики
- •Выводы
- •Конфигурация и ввод
- •Конфигурация состояния
- •Структура данных конфигурации среды выполнения
- •Конфигурация сборки
- •Сборка модуля из входных данных
- •Выводы
- •Генерирование конкретного синтаксического дерева
- •Парсер/токенизатор CPython
- •Абстрактные синтаксические деревья
- •Важные термины
- •Пример: добавление оператора «почти равно»
- •Выводы
- •Компилятор
- •Исходные файлы
- •Важные термины
- •Создание экземпляра компилятора
- •Флаги будущей функциональности и флаги компилятора
- •Таблицы символических имен
- •Основная компиляция
- •Ассемблер
- •Создание объекта кода
- •Использование Instaviz для вывода объекта кода
- •Пример: реализация оператора «почти равно»
- •Выводы
- •Цикл вычисления
- •Исходные файлы
- •Важные термины
- •Построение состояния потока
- •Построение объектов кадров
- •Выполнение кадра
- •Стек значений
- •Пример: добавление элемента в список
- •Выводы
- •Управление памятью
- •Выделение памяти в C
- •Проектирование системы управления памятью Python
- •Аллокаторы памяти CPython
- •Область выделения объектной памяти и PyMem
- •Область выделения сырой памяти
- •Нестандартные области выделения памяти
- •Санитайзеры выделенной памяти
- •Арена памяти PyArena
- •Подсчет ссылок
- •Сборка мусора
- •Выводы
- •Параллелизм и конкурентность
- •Модели параллелизма и конкурентности
- •Структура процесса
- •Многопроцессорный параллелизм
- •Многопоточность
- •Асинхронное программирование
- •Генераторы
- •Сопрограммы
- •Асинхронные генераторы
- •Субинтерпретаторы
- •Выводы
- •Объекты и типы
- •Примеры этой главы
- •Встроенные типы
- •Типы объектов
- •Тип type
- •Типы bool и long
- •Тип строки Юникода
- •Словари
- •Выводы
- •Стандартная библиотека
- •Модули Python
- •Модули Python и C
- •Набор тестов
- •Запуск набора тестов в Windows
- •Запуск набора тестов в Linux или macOS
- •Флаги тестирования
- •Запуск конкретных тестов
- •Модули тестирования
- •Вспомогательные средства тестирования
- •Выводы
- •Отладка
- •Обработчик сбоев
- •Компиляция поддержки отладки
- •LLDB для macOS
- •Отладчик Visual Studio
- •Отладчик CLion
- •Выводы
- •Бенчмаркинг, профилирование и трассировка
- •Использование timeit для микробенчмарка
- •Использование набора тестов производительности Python
- •Профилирование кода Python с использованием cProfile
- •Выводы
- •Что дальше?
- •Создание расширений C для CPython
- •Улучшение приложений Python
- •Участие в проекте CPython
- •Дальнейшее обучение
- •Препроцессор C
- •Базовый синтаксис C
- •Выводы
- •Благодарности
56 Компиляция CPython
В этой книге будут приводиться сессии REPL c примерами команд. Я рекомендую использовать отладочный двоичный файл для выполнения этих сессий REPL на случай, если вы захотите установить точки останова в коде.
Чтобы упростить навигацию в коде, в окне Solution переключитесь в режим Folder с помощью кнопки справа от значка Home:
ПРОФИЛЬНАЯ ОПТИМИЗАЦИЯ
Сборка на macOS, Linux и Windows поддерживает флаги профильной оптимизации (PGO). Режим PGO не был придуман командой Python; он встречается во многих компиляторах, включая те, что используются CPython.
PGO выполняет исходную компиляцию, после чего профилирует приложение, выполняя серию тестов. Затем профиль анализируется, и компилятор вносит в двоичный файл изменения для повышения производительности.
Для CPython на этапе профилирования запускается команда python -m test --pgo, которая выполняет регрессионные тесты, заданные в Lib test libregrtest pgo.py. Эти тесты были выбраны специально, потому что они используют часто встречающиеся модули расширений C и типы.
Книги для программистов: https://t.me/booksforits
Профильная оптимизация 57
ПРИМЕЧАНИЕ
Процесс PGO занимает много времени, поэтому для ускорения компи ляции я исключил его из списков рекомендуемых шагов, приводимых в книге.
Если вы хотите использовать специально cкомпилированные версии CPython на продакшен, выполните команду ./configure с флагом --with- pgo на Linux и macOS или добавьте флаг --pgo в build.bat на Windows.
Так как оптимизация привязана к платформе и архитектуре, для которой проводилось профилирование, профили PGO не могут совместно использоваться в разных операционных системах или архитектурах процессоров. Дистрибутивы CPython на Python.org уже прошли PGO, и если вы протестируете производительность скомпилированного в базовой конфигурации двоичного файла, он будет медленнее загруженного с Python.org.
Профильные оптимизации на Windows, macOS и Linux включают следующие проверки и улучшения:
zz Встроенные функции: если функция часто вызывается из другой функции, она будет вложена (то есть скопирована в вызывающую функцию) для сокращения размера стека.
zz Прогнозирование виртуальных вызовов и вложенность: если вызов виртуальной функции часто приходится на конкретную функцию, то PGO может вставить условно выполняемый прямой вызов этой функции. Это позволяет вложить непосредственный вызов.
zz Оптимизация распределения регистров: на основании результатов профилирования PGO оптимизирует распределение регистров.
zz Оптимизация базовых блоков: этот прием оптимизации позволяет разместить часто выполняемые базовые блоки (которые временно выполняются в заданных границах) в одной локальности или наборе страниц. Таким образом сводится к минимуму количество используемых страниц, что минимизирует лишние затраты памяти.
zz Оптимизация активных участков: функции, на выполнение которых программа тратит большую часть времени, могут оптимизироваться для ускорения.
Книги для программистов: https://t.me/booksforits
58 Компиляция CPython
zz Оптимизация размещения функций: после того, как PGO проанализирует граф вызовов, функции, которые обычно располагаются на одном пути выполнения, перемещаются в одну секцию скомпилированного приложения.
zz Оптимизация условных ветвлений: PGO может проанализировать ветви принятия решений (такие, как if … else if или switch) и выявить самый частый используемый путь. Например, если команда switch содержит 10 вариантов (путей) и один из них используется в 95 % случаев, то он перемещается в начало, чтобы выполняться раньше других в кодовом пути.
zz Отделение мертвых зон: код, не вызываемый в процессе PGO, перемещается в отдельную секцию приложения.
ВЫВОДЫ
В этой главе вы узнали, как скомпилировать исходный код CPython в рабочий интерпретатор. Эта информация пригодится, когда мы займемся исследованием и адаптацией исходного кода.
Возможно, в ходе работы с CPython вам придется повторять действия по компиляции десятки и даже сотни раз. Если вы сможете адаптировать свою среду разработки и назначить сочетание клавиш для повторной компиляции, лучше сделать это прямо сейчас и сэкономить себе немало времени в будущем.
Книги для программистов: https://t.me/booksforits