Перейти к основному содержимому

Запуск Ignition и TurboFan

· 6 мин. чтения
команда V8

Сегодня мы рады объявить о запуске нового конвейера выполнения JavaScript для V8 v5.9, который достигнет Stable-версии Chrome в v59. С новым конвейером мы достигаем значительных улучшений производительности и значительной экономии памяти в реальных приложениях JavaScript. Мы обсудим цифры более подробно в конце этого поста, но сначала давайте взглянем на сам конвейер.

Новый конвейер построен на основе Ignition, интерпретатора V8, и TurboFan, нового оптимизирующего компилятора V8. Эти технологии должны быть знакомы вам, если вы следили за блогом V8 в последние несколько лет, но переход к новому конвейеру знаменует собой большое новое достижение для обоих.

Логотип Ignition, совершенно нового интерпретатора V8
Логотип TurboFan, совершенно нового оптимизирующего компилятора V8

Впервые Ignition и TurboFan используются универсально и исключительно для выполнения JavaScript в V8 v5.9. Кроме того, начиная с версии 5.9, Full-codegen и Crankshaft, технологии, которые служили V8 с 2010 года, больше не используются в V8 для выполнения JavaScript, поскольку они больше не могут идти в ногу с новыми функциями языка JavaScript и оптимизациями, которых требуют эти функции. Мы планируем полностью удалить их в ближайшее время. Это означает, что общая архитектура V8 станет намного проще и более удобной для поддержки.

Долгий путь

Объединенный конвейер Ignition и TurboFan находился в разработке почти 3½ года. Он представляет собой кульминацию коллективного опыта команды V8, полученного в процессе измерения производительности реального JavaScript и внимательного рассмотрения недостатков Full-codegen и Crankshaft. Это основа, на которой мы сможем продолжать оптимизировать весь язык JavaScript в течение многих лет.

Проект TurboFan изначально начался в конце 2013 года с целью устранения недостатков Crankshaft. Crankshaft может оптимизировать только подмножество языка JavaScript. Например, он не был разработан для оптимизации JavaScript-кода с использованием структурированной обработки исключений, то есть блоков кода, обозначенных ключевыми словами JavaScript try, catch и finally. Добавление поддержки новых функций языка в Crankshaft является сложной задачей, поскольку такие функции почти всегда требуют написания архитектурно-специфичного кода для девяти поддерживаемых платформ. Кроме того, архитектура Crankshaft ограничена в степени генерации оптимального машинного кода. Она может выдавать только определенный уровень производительности JavaScript, несмотря на необходимость команды V8 поддерживать более десяти тысяч строк кода на каждую архитектуру чипа.

TurboFan был с самого начала разработан не только для оптимизации всех функций языка, содержащихся в стандарте JavaScript на тот момент, ES5, но и всех будущих функций, запланированных для ES2015 и далее. Он вводит многослойный дизайн компилятора, который обеспечивает четкое разделение между высокоуровневыми и низкоуровневыми оптимизациями компилятора, что значительно упрощает добавление новых функций языка без модификации архитектурно-специфичного кода. TurboFan вводит явную фазу компиляции выбора инструкций, что позволяет изначально писать гораздо меньше архитектурно-специфичного кода для каждой поддерживаемой платформы. С этой новой фазой архитектурно-специфичный код пишется один раз и редко нуждается в изменении. Эти и другие решения приводят к более удобному для поддержки и расширяемому оптимизирующему компилятору для всех архитектур, поддерживаемых V8.

Изначальная мотивация создания интерпретатора Ignition для V8 заключалась в уменьшении потребления памяти на мобильных устройствах. До Ignition код, созданный базовым компилятором Full-codegen в V8, обычно занимал почти треть общего JavaScript-кучи в Chrome. Это оставляло меньше места для фактических данных веб-приложений. Когда Ignition был включен для Chrome M53 на Android-устройствах с ограниченной оперативной памятью, объем памяти, необходимый для базового, неоптимизированного JavaScript-кода, уменьшился в девять раз на мобильных устройствах на основе ARM64.

Позже команда V8 воспользовалась тем фактом, что байт-код Ignition может быть использован для непосредственной генерации оптимизированного машинного кода с помощью TurboFan, вместо того чтобы перекомпилировать исходный код, как это делал Crankshaft. Байт-код Ignition предоставляет более чистую и менее подверженную ошибкам базовую модель выполнения в V8, упрощая механизм деоптимизации, который является ключевой особенностью адаптивной оптимизации V8. Наконец, так как создание байт-кода происходит быстрее, чем генерация базового скомпилированного кода Full-codegen, активация Ignition обычно ускоряет запуск скриптов и, в свою очередь, загрузку веб-страниц.

Благодаря тесной связи дизайна Ignition и TurboFan, архитектура имеет еще больше преимуществ. Например, вместо написания высокопроизводительных обработчиков байт-кода Ignition вручную, команда V8 использует промежуточное представление TurboFan, чтобы определить функциональность обработчиков и позволяет TurboFan выполнять их оптимизацию и финальную генерацию кода для множества поддерживаемых платформ V8. Это гарантирует хорошую производительность Ignition на всех поддерживаемых архитектурах процессоров V8, одновременно устраняя необходимость поддерживать девять отдельных платформенных портов.

Подсчитываем показатели

Оставив историю, теперь давайте взглянем на реальную производительность и потребление памяти нового конвейера.

Команда V8 постоянно отслеживает производительность в реальных случаях использования с помощью фреймворка Telemetry - Catapult. Ранее в этом блоге мы обсуждали, почему так важно использовать данные из реальных тестов для управления нашей работой по оптимизации производительности, а также то, как мы используем WebPageReplay вместе с Telemetry для достижения этого. Переход на Ignition и TurboFan показывает улучшения производительности в реальных тестах. В частности, новый конвейер демонстрирует значительное ускорение взаимодействия с пользователем в тестах для известных веб-сайтов:

Сокращение времени, затраченного на V8 для тестов взаимодействия с пользователем

Хотя Speedometer является синтетическим тестом, мы ранее выяснили, что он лучше всего моделирует рабочую нагрузку современного JavaScript, чем другие синтетические тесты. Переход на Ignition и TurboFan улучшает показатель Speedometer для V8 на 5%-10%, в зависимости от платформы и устройства.

Новый конвейер также ускоряет работу серверного JavaScript. AcmeAir, тест для Node.js, который моделирует серверную реализацию вымышленной авиакомпании, работает более чем на 10% быстрее с V8 версии 5.9.

Улучшения для веба и бенчмарков Node.js

Ignition и TurboFan также снижают общую память, потребляемую V8. В Chrome M59 новый конвейер уменьшил footprint памяти V8 на настольных и высокопроизводительных мобильных устройствах на 5-10%. Это снижение произошло благодаря внедрению экономии памяти Ignition, которые были ранее освещены в этом блоге, для всех устройств и платформ, поддерживаемых V8.

Эти улучшения — только начало. Новый конвейер Ignition и TurboFan прокладывает путь для дальнейших оптимизаций, которые повысят производительность JavaScript и сократят footprint V8 как в Chrome, так и в Node.js на годы вперед. Мы с нетерпением ждем возможности поделиться этими улучшениями с вами, по мере их внедрения для разработчиков и пользователей. Следите за обновлениями.