Facebook открыл код Cinder, форка CPython, используемого в Instagram
5 мая 2021 года
Компания Facebook опубликовала исходные тексты проекта Cinder, развивающего ответвление от CPython 3.8.5, основной эталонной реализации языка программирования Python. Cinder применяется в рабочей инфраструктуре Facebook для обеспечения функционирования сервиса Instagram и включает оптимизации для повышения производительности.
Код опубликован для обсуждения возможности переноса подготовленных оптимизаций в основной состав CPython и для помощи другим проектам, занимающимся повышением производительности CPython. При этом Facebook не собирается поддерживать Cinder в форме отдельного открытого проекта и код представлен в том виде, в котором используется в инфраструктуре компании, без дополнительного причёсывания кода и документирования. Cinder также не пытаются продвигать как альтернативу CPython - основной целью разработки является желание улучшить сам CPython.
Код отмечается как достаточно надёжный и проверенный в рабочих окружениях, но в случае выявления проблем их придётся решать самостоятельно, так как Facebook не гарантирует, что будет реагировать на внешние сообщения об ошибках и pull-запросы. При этом Fecebook не исключает конструктивное сотрудничество с сообществом и готов обсудить идеи как сделать Cinder ещё быстрее или как ускорить перенос подготовленных изменений в основной состав CPython.
Основные оптимизации, реализованные в Cinder:
- Inline-кэширование байткода ("shadow bytecode"). Суть метода в выявлении ситуаций выполнения типового опкода, которые можно опитимизировать, и динамической замены подобного опкода на более быстрые специализированные варианты (например, замена часто вызываемых функций).
- Активное вычисление сопрограмм (Eager coroutine evaluation). Для вызовов async-функций, которые сразу обрабатываются (await не приводит к ожиданию и функция достигает оператора return раньше), результат подобных функций напрямую подставляется без создания сопрограммы и без привлечения цикла обработки событий. В применяемом в Facebook коде, в котором активно используется async/await, оптимизация приводит к ускорению примерно на 5%.
- Выборочная JIT-компиляция на уровне отдельных методов и функций (method-at-a-time). Включается через опцию "-X jit" или переменную окружения PYTHONJIT=1 и позволяет ускорить выполнение многих тестов производительности в 1.5-4 раза. Так как JIT-компиляция актуальна только для часто выполняемых функций, нецелесообразно применять её для редко используемых функций, накладные расходы на компиляцию которых могут лишь замедлить выполнение программы.
Через опцию "-X jit-list-file=/path/to/jitlist.txt" или переменную окружения "PYTHONJITLISTFILE=/path/to/jitlist.txt" можно указать файл со списком функций, для которых можно использовать JIT (формат path.to.module:funcname или path.to.module:ClassName.method_name). Список функций для которых следует включить JIT можно определить на основе результатов профилирования. В будущем ожидается поддержка динамической JIT-компиляции на основе внутреннего анализа частоты вызова функций, но с учётом специфики запуска процессов в Instagram, предпочтительней JIT-компиляция на начальном этапе.
JIT вначале преобразует байткод Python в высокоуровневное промежуточное представление (HIR), которое достаточно близко к байткоду Python, но рассчитано на использование регистровой виртуальной машины, вместо стековой, а также использует информацию о типах и дополнительные детали, важные для производительности (например, подсчёт ссылок). HIR затем преобразуется в форму SSA (static single assignment) и проходит стадии оптимизации, учитывающие результаты подсчёта ссылок и данные о потреблении памяти. В итоге генерируется низкоуровневное промежуточное представление (LIR), близкое к языку ассемблер. После ещё одной фазы оптимизаций на основе LIR при помощи библиотеки asmjit генерируются ассемблерные инструкции.
- Режим strict для модулей. Функциональность включает три компонента : Тип StrictModule. Статический анализатор, способный определить, что выполнение модуля не оказывает влияние на код за пределами этого модуля. Загрузчик модулей, определяющий, что модули переведены в режим
strict (в коде указывается "import __strict__"), проверяющий отсутствие пересечений с другими модулями и загружающих strict-модули в sys.modules в виде объекта StrictModule.
- Static Python - экспериментальный компилятор байткода, использующий аннотации типов для генерации байткода, специфичного для каждого типа и выполняемого быстрее благодаря применению JIT-компиляции. В некоторых тестах сочетание Static Python и JIT демонстрирует повышение производительно до 7 раз, по сравнению с типовым CPython. Во многих ситуациях результаты оцениваются как близкие к применению компиляторов MyPyC и Cython.
Источники править
Любой участник может оформить статью: добавить иллюстрации, викифицировать, заполнить шаблоны и добавить категории.
Любой редактор может снять этот шаблон после оформления и проверки.
Комментарии
Если вы хотите сообщить о проблеме в статье (например, фактическая ошибка и т. д.), пожалуйста, используйте обычную страницу обсуждения.
Комментарии на этой странице могут не соответствовать политике нейтральной точки зрения, однако, пожалуйста, придерживайтесь темы и попытайтесь избежать брани, оскорбительных или подстрекательных комментариев. Попробуйте написать такие комментарии, которые заставят задуматься, будут проницательными или спорными. Цивилизованная дискуссия и вежливый спор делают страницу комментариев дружелюбным местом. Пожалуйста, подумайте об этом.
Несколько советов по оформлению реплик:
- Новые темы начинайте, пожалуйста, снизу.
- Используйте символ звёздочки «*» в начале строки для начала новой темы. Далее пишите свой текст.
- Для ответа в начале строки укажите на одну звёздочку больше, чем в предыдущей реплике.
- Пожалуйста, подписывайте все свои сообщения, используя четыре тильды (~~~~). При предварительном просмотре и сохранении они будут автоматически заменены на ваше имя и дату.
Обращаем ваше внимание, что комментарии не предназначены для размещения ссылок на внешние ресурсы не по теме статьи, которые могут быть удалены или скрыты любым участником. Тем не менее, на странице комментариев вы можете сообщить о статьях в СМИ, которые ссылаются на эту заметку, а также о её обсуждении на сторонних ресурсах.