Новости о продуктах

Повышение производительности Android: представляем AutoFDO для ядра

Время на чтение: 4 минуты
Посмотреть профиль пользователя Charles Munger
Yabin Cui Разработчик программного обеспечения

Мы – команда, которая занимается набором инструментов 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.

boosting_2.png

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

Как это работает: конвейер

Наша стратегия развертывания включает сложный конвейер, который обеспечивает актуальность профилей и стабильную производительность.

boosting_3.png

Шаг 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 сама основа ОС оптимизирована для того, как вы используете устройство каждый день.

Автор:
Продолжить чтение