Повышение производительности Android: представляем AutoFDO для ядра
Время на чтение: 4 минуты
Мы команда, которая занимается набором инструментов LLVM для Android. Одна из наших главных задач – повысить производительность Android с помощью методов оптимизации в экосистеме LLVM. Мы постоянно ищем способы сделать Android быстрее, плавнее и эффективнее. Хотя большая часть нашей работы по оптимизации происходит в пользовательском пространстве, ядро остается сердцем системы. Сегодня мы расскажем, как внедряем автоматическую оптимизацию на основе обратной связи (AutoFDO) в ядро Android, чтобы значительно повысить производительность для пользователей.
Что такое AutoFDO?
При стандартной сборке ПО компилятор принимает тысячи мелких решений, например о том, следует ли встроить функцию и какая ветвь условного оператора, скорее всего, будет выполнена, на основе статических подсказок кода.Хотя эти эвристики полезны, они не всегда точно предсказывают выполнение кода при реальном использовании телефона.
AutoFDO меняет это, используя реальные шаблоны выполнения для управления компилятором. Эти шаблоны представляют собой наиболее распространенные пути выполнения инструкций, по которым код проходит во время фактического использования, зафиксированные путем записи истории ветвления ЦП. Хотя эти данные можно собирать с устройств, для ядра мы синтезируем их в лабораторных условиях, используя репрезентативные рабочие нагрузки, например запуск 100 самых популярных приложений. Для сбора этих данных мы используем профилировщик выборки, который определяет, какие части кода используются часто, а какие – редко. Когда мы пересобираем ядро с этими профилями, компилятор может принимать гораздо более разумные решения по оптимизации, адаптированные к реальным рабочим нагрузкам Android.
Чтобы понять влияние этой оптимизации, рассмотрим следующие ключевые факты:
- На Android ядро занимает около 40% процессорного времени.
- Мы уже используем AutoFDO для оптимизации нативных исполняемых файлов и библиотек в пользовательском пространстве. Это позволило ускорить холодный запуск приложений примерно на 4 %, а загрузку – на 1 %.
Реальные примеры повышения производительности
Мы заметили значительные улучшения ключевых показателей Android, используя профили из контролируемых лабораторных сред. Эти профили были собраны с помощью сканирования и запуска приложений и измерены на устройствах Pixel с ядрами 6.1, 6.6 и 6.12.
Наиболее заметные улучшения перечислены ниже. Подробную информацию о профилях AutoFDO для этих версий ядер можно найти в соответствующих репозиториях ядер Android для android16-6.12 и android15-6.6.
Это не просто теоретические цифры. Они обеспечивают более быстрый интерфейс, ускоренное переключение между приложениями, увеличенное время работы от батареи и в целом более отзывчивое устройство для конечного пользователя.
Как это работает: конвейер
Наша стратегия развертывания включает сложный конвейер, который обеспечивает актуальность профилей и стабильную производительность.
Шаг 1. Сбор профилей
Для профилирования двоичных файлов пользовательского пространства мы используем внутренний парк тестовых устройств, а для универсального образа ядра (GKI) – контролируемую лабораторную среду. Отделение профилирования от цикла выпуска устройств позволяет гибко и немедленно обновлять профили независимо от развернутых версий ядра. Важно, что тесты подтверждают: эти лабораторные данные обеспечивают прирост производительности, сопоставимый с приростом производительности реальных парков.
- Инструменты и среда. Мы прошиваем тестовые устройства с помощью последнего образа ядра и используем simpleperf для захвата потоков выполнения инструкций. Этот процесс опирается на аппаратные возможности записи истории ветвления, в частности на ARM Embedded Trace Extension (ETE) и ARM Trace Buffer Extension (TRBE) на устройствах Pixel.
- Рабочие нагрузки. Мы создаем репрезентативную рабочую нагрузку, используя 100 самых популярных приложений из Android App Compatibility Test Suite (C-Suite). Чтобы собирать максимально точные данные, мы уделяем особое внимание следующим аспектам:
- Запуск приложения. Оптимизация задержек, наиболее заметных для пользователей.
- Сканирование приложений с помощью ИИ: имитация непрерывных, развивающихся взаимодействий с пользователем.
- Мониторинг всей системы. Отслеживание не только действий в активных приложениях, но и критически важных фоновых рабочих нагрузок и межпроцессного взаимодействия.
- Проверка. Эта синтезированная рабочая нагрузка на 85% похожа на шаблоны выполнения, собранные из нашего внутреннего парка.
- Целевые данные. Повторяя эти тесты достаточное количество раз, мы получаем высокоточные шаблоны выполнения, которые точно отражают реальное взаимодействие пользователей с самыми популярными приложениями. Кроме того, этот расширяемый фреймворк позволяет нам тесно интегрировать дополнительные рабочие нагрузки и тесты, чтобы расширить охват.
Шаг 2. Обработка профиля
Мы обрабатываем необработанные данные трассировки, чтобы убедиться, что они чистые, эффективные и готовы к компиляции.
- Агрегирование. Мы объединяем данные, полученные в результате нескольких запусков тестов и с разных устройств, в единое представление.
- Преобразование. Мы преобразуем необработанные трассировки в формат профиля AutoFDO, при необходимости отфильтровывая ненужные символы.
- Обрезка профилей. Мы удаляем из профилей данные о "холодных" функциях, чтобы для них можно было использовать стандартную оптимизацию. Это предотвращает регрессии в редко используемом коде и позволяет избежать ненужного увеличения размера двоичного файла.
Шаг 3. Тестирование профиля
Перед развертыванием профили проходят строгую проверку, чтобы обеспечить стабильную производительность без рисков для стабильности.
- Анализ профиля и двоичного кода. Мы тщательно сравниваем контент нового профиля (включая горячие функции, количество выборок и размер профиля) с предыдущими версиями. Мы также используем профиль для создания нового образа ядра, анализируя двоичные файлы, чтобы убедиться, что изменения в текстовом разделе соответствуют ожиданиям.
- Проверка производительности. Мы проводим целевые тесты производительности нового образа ядра. Это подтверждает, что он сохраняет улучшения производительности, установленные предыдущими базовыми показателями.
Постоянные обновления
Код со временем меняется, поэтому статический профиль в конечном итоге потеряет свою эффективность. Чтобы поддерживать максимальную эффективность, мы постоянно запускаем конвейер для регулярных обновлений:
- Регулярное обновление. Мы обновляем профили в ветвях LTS ядра Android перед каждым выпуском GKI, чтобы в каждой сборке были последние данные профиля.
- Дальнейшее развитие. Сейчас мы выпускаем эти обновления для веток
android16-6.12иandroid15-6.6, а в будущем добавим поддержку более новых версий GKI, напримерandroid17-6.18.
Обеспечение стабильности
Часто возникает вопрос, не приводит ли оптимизация на основе профиля к проблемам со стабильностью. Поскольку AutoFDO в основном влияет на эвристику компилятора, например на встраивание функций и макет кода, а не на логику исходного кода, он сохраняет функциональную целостность ядра. Эта технология уже доказала свою эффективность в больших масштабах, служа стандартной оптимизацией для библиотек платформы Android, ChromeOS и собственной серверной инфраструктуры Google на протяжении многих лет.
Чтобы обеспечить стабильность работы, мы по умолчанию применяем консервативную стратегию. Функции, не зафиксированные в профилях высокой точности, оптимизируются с помощью стандартных методов компилятора. Это гарантирует, что "холодные" или редко выполняемые части ядра будут вести себя точно так же, как и в стандартной сборке, предотвращая регрессию производительности или неожиданное поведение в крайних случаях.
Планы на будущее
В настоящее время мы развертываем AutoFDO в ветках android16-6.12 и android15-6.6. Помимо этого первоначального выпуска, мы видим несколько перспективных направлений для дальнейшего улучшения технологии:
- Расширение охвата. Мы планируем развернуть профили AutoFDO для более новых версий ядра GKI и дополнительных целей сборки, помимо текущей поддержки
aarch64. - Оптимизация модулей GKI. Сейчас оптимизация применяется к основному двоичному файлу ядра (
vmlinux). Если расширить AutoFDO на модули GKI, это может повысить производительность большей части подсистемы ядра. - Поддержка модулей поставщиков. Мы также планируем добавить поддержку AutoFDO для модулей поставщиков, созданных с помощью Driver Development Kit (DDK). Поддержка уже доступна в нашей системе сборки (Kleaf) и инструментах профилирования (simpleperf). Это позволяет поставщикам применять те же методы оптимизации к своим драйверам оборудования.
- Более широкий охват профилей. Можно собирать профили из большего количества алгоритмов достижения цели, чтобы оптимизировать их.
Благодаря AutoFDO ядро Android оптимизировано для повседневного использования.
-
Новости о продуктахСегодня на Саммите для разработчиков Android мы объявляем о широкой доступности многих инструментов и API, которые помогут вам преодолевать повседневные трудности и дадут больше гибкости при создании отличных приложений для Android.
Matthew McCullough • Время на чтение: 4 минуты -
Новости о продуктахAndroid Studio Rabbit 2 теперь стабильна и готова к использованию в рабочей среде. В этом выпуске представлены ключевые функции, которые помогут вам в разработке, например Bring Your Own Agent, новые функции XR Emulator, обновление LeakCanary, новый инструмент управления навыками агента, код-ревью с помощью ИИ и многое другое.
Matthew Warner • Время на чтение: 3 минуты -
Новости о продуктахПриложения, предназначенные для предстоящего выпуска Android, больше не смогут напрямую записывать данные в контакты с помощью разрешения WRITE_CONTACTS.
Roxanna Aliabadi Walker • Время на чтение: 6 минут
Получайте еженедельную рассылку с последними новостями о разработке для Android.