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

Запуск 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 на годы вперед. Мы с нетерпением ждем возможности поделиться этими улучшениями с вами, по мере их внедрения для разработчиков и пользователей. Следите за обновлениями.