Система сборки Android для Android 13 и более ранних версий поддерживает использование оптимизации на основе профиля (PGO) Clang для собственных модулей Android, в которых есть правила сборки blueprint. На этой странице описано, как работает Clang PGO, как создавать и обновлять профили, используемые для PGO, и как интегрировать PGO с системой сборки (с примером использования).
Примечание. В этом документе описывается использование PGO на платформе Android. Чтобы узнать, как использовать PGO в приложении Android, посетите эту страницу.
О Clang PGO
Clang может выполнять оптимизацию на основе профиля, используя два типа профилей:
- Профили на основе инструментов создаются на основе целевой программы с инструментами. Эти профили подробные и создают большую нагрузку на время выполнения.
- Профили на основе выборки обычно создаются с помощью счетчиков аппаратного обеспечения. Они не создают большой нагрузки на систему и могут собираться без изменения двоичного кода. Они менее подробны, чем профили, созданные на основе данных об инструментах.
Все профили должны быть созданы на основе типичной рабочей нагрузки, которая отражает обычное поведение приложения. Clang поддерживает профили на основе AST (-fprofile-instr-generate) и LLVM IR (-fprofile-generate)). В Android для PGO на основе инструментов поддерживаются только профили на основе LLVM IR.
Для сборки с целью сбора профилей необходимы следующие флаги:
-fprofile-generateдля инструментов на основе ИК-излучения. При этом серверная часть использует подход взвешенного минимального остовного дерева, чтобы уменьшить количество точек инструментирования и оптимизировать их размещение на ребрах с малым весом (используйте этот параметр также для шага связывания). Драйвер Clang автоматически передает компоновщику среду выполнения профилирования (libclang_rt.profile-arch-android.a). Эта библиотека содержит процедуры для записи профилей на диск при выходе из программы.-gline-tables-onlyдля сбора профиля на основе выборки, чтобы создать минимальные сведения для отладки.
Профиль можно использовать для PGO с помощью -fprofile-use=pathname или -fprofile-sample-use=pathname для профилей на основе инструментов и выборки соответственно.
Примечание. Если в код вносятся изменения и Clang больше не может использовать данные профиля, он генерирует предупреждение -Wprofile-instr-out-of-date.
Использовать PGO
Использование PGO включает следующие этапы:
- Создайте библиотеку или исполняемый файл с инструментарием, передав
-fprofile-generateкомпилятору и компоновщику. - Собирайте профили, выполняя типичную рабочую нагрузку на инструментированном двоичном файле.
- Выполните постобработку профилей с помощью утилиты
llvm-profdata(подробнее об обработке файлов профилей LLVM…). - Используйте профили, чтобы применить PGO, передав
-fprofile-use=<>.profdataкомпилятору и компоновщику.
Для PGO в Android профили должны собираться в автономном режиме и проверяться вместе с кодом, чтобы обеспечить воспроизводимость сборок. Профили можно использовать по мере развития кода, но их необходимо периодически обновлять (или когда Clang предупреждает, что профили устарели).
Сбор профилей
Clang может использовать профили, собранные при запуске тестов производительности с помощью инструментированной сборки библиотеки или путем выборки аппаратных счетчиков при запуске теста производительности. В настоящее время Android не поддерживает сбор профилей на основе выборки, поэтому вам необходимо собирать профили с помощью инструментированной сборки:
- Определите тест производительности и набор библиотек, которые он использует.
- Добавьте свойства
pgoв контрольную точку и библиотеки (подробности ниже). - Создайте сборку Android с инструментированной копией этих библиотек, используя:
make ANDROID_PGO_INSTRUMENT=benchmark
benchmark – это плейсхолдер, который идентифицирует набор библиотек, используемых во время сборки. Фактические входные данные представителя (и, возможно, другой исполняемый файл, который ссылается на библиотеку, подвергаемую тестированию) не относятся к PGO и выходят за рамки этого документа.
- Установите или синхронизируйте сборку с инструментарием на устройстве.
- Запустите тест, чтобы собрать профили.
- Используйте инструмент
llvm-profdata(описан ниже) для постобработки профилей и подготовки их к проверке в дереве исходного кода.
Использовать профили при сборке
Проверьте профили в toolchain/pgo-profiles в дереве Android. Название должно совпадать с указанным в дочернем свойстве profile_file свойства pgo для библиотеки. Система сборки автоматически передает файл профиля в Clang при сборке библиотеки. Переменную среды ANDROID_PGO_DISABLE_PROFILE_USE
можно задать как true, чтобы временно отключить PGO и оценить ее эффективность.
Чтобы указать дополнительные каталоги профилей для определенного продукта, добавьте их в переменную PGO_ADDITIONAL_PROFILE_DIRECTORIES в файле BoardConfig.mk. Если указаны дополнительные пути, профили в этих путях переопределяют профили в toolchain/pgo-profiles.
При создании образа выпуска с использованием цели dist для make система сборки записывает имена отсутствующих файлов профиля в $DIST_DIR/pgo_profile_file_missing.txt. Вы можете проверить этот файл, чтобы узнать, какие файлы профиля были случайно удалены (что незаметно отключает PGO).
Включите PGO в файлах Android.bp
Чтобы включить PGO в файлах Android.bp для нативных модулей, просто укажите свойство pgo. У этого свойства есть следующие вложенные свойства:
| Ресурс | Описание |
|---|---|
instrumentation
|
Установите значение true для PGO с использованием инструментов. Значение по умолчанию – false. |
sampling
|
Для оптимизации на основе профиля с использованием выборки задайте значение true. Значение по умолчанию – false. |
benchmarks
|
Список строк. Этот модуль предназначен для профилирования, если в параметре сборки ANDROID_PGO_INSTRUMENT указан какой-либо тест из списка. |
profile_file
|
Файл профиля (относительно toolchain/pgo-profile), который будет использоваться с PGO. Если файл не существует, сборка предупреждает об этом, добавляя его в $DIST_DIR/pgo_profile_file_missing.txt, если только свойство enable_profile_use не имеет значение false ИЛИ переменная сборки ANDROID_PGO_NO_PROFILE_USE не имеет значение true. |
enable_profile_use
|
Установите значение false, если профили не должны использоваться во время сборки. Можно использовать во время начальной загрузки, чтобы включить сбор профилей или временно отключить PGO. Значение по умолчанию – true. |
cflags
|
Список дополнительных флагов, которые будут использоваться при сборке с инструментами. |
Пример модуля с PGO:
cc_library { name: "libexample", srcs: [ "src1.cpp", "src2.cpp", ], static: [ "libstatic1", "libstatic2", ], shared: [ "libshared1", ] pgo: { instrumentation: true, benchmarks: [ "benchmark1", "benchmark2", ], profile_file: "example.profdata", } }
Если контрольные показатели benchmark1 и benchmark2 отражают типичное поведение для библиотек libstatic1, libstatic2 или libshared1, то свойство pgo этих библиотек также может включать контрольные показатели. Модуль defaults в Android.bp может включать общую спецификацию pgo для набора библиотек, чтобы не повторять одни и те же правила сборки для нескольких модулей.
Чтобы выбрать другие файлы профиля или выборочно отключить PGO для архитектуры, укажите свойства profile_file, enable_profile_use и cflags для каждой архитектуры. Пример (целевая архитектура выделена жирным шрифтом):
cc_library { name: "libexample", srcs: [ "src1.cpp", "src2.cpp", ], static: [ "libstatic1", "libstatic2", ], shared: [ "libshared1", ], pgo: { instrumentation: true, benchmarks: [ "benchmark1", "benchmark2", ], } target: { android_arm: { pgo: { profile_file: "example_arm.profdata", } }, android_arm64: { pgo: { profile_file: "example_arm64.profdata", } } } }
Чтобы устранить ссылки на библиотеку времени выполнения профилирования во время профилирования на основе инструментов, передайте флаг сборки -fprofile-generate компоновщику. Статические библиотеки, инструментированные с помощью PGO, все общие библиотеки и любые двоичные файлы, которые напрямую зависят от статической библиотеки, также должны быть инструментированы для PGO. Однако для таких общих библиотек или исполняемых файлов не обязательно использовать профили PGO, и их свойство enable_profile_use можно установить в значение false.
В остальных случаях PGO можно применять к любой статической библиотеке, общей библиотеке или исполняемому файлу.
Как работать с файлами профиля LLVM
При выполнении библиотеки с инструментарием или исполняемого файла создается файл профиля с именем default_unique_id_0.profraw в /data/local/tmp (где unique_id – это числовой хеш, уникальный для этой библиотеки). Если этот файл уже существует, во время записи профилей среда выполнения профилирования объединяет новый профиль со старым. Обратите внимание, что разработчики приложений не могут получить доступ к /data/local/tmp. Вместо этого они могут использовать, например, /storage/emulated/0/Android/data/packagename/files.
Чтобы изменить расположение файла профиля, задайте переменную среды LLVM_PROFILE_FILE во время выполнения.
Затем утилита llvm-profdata используется для преобразования файла .profraw (и, возможно, объединения нескольких файлов .profraw) в файл .profdata:
llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>
profile.profdata, а затем добавить его в дерево исходного кода для использования при сборке.
Если во время тестирования загружается несколько инструментированных двоичных файлов или библиотек, каждая библиотека создает отдельный файл .profraw с уникальным идентификатором. Как правило, все эти файлы можно объединить в один файл .profdata и использовать для создания PGO. Если библиотека используется в другом тесте, ее необходимо оптимизировать с помощью профилей из обоих тестов. В этом случае полезен вариант show
llvm-profdata:
llvm-profdata merge -output=default_unique_id.profdata default_unique_id_0.profraw llvm-profdata show -all-functions default_unique_id.profdata
Чтобы сопоставить unique_id с отдельными библиотеками, выполните поиск по каждому unique_id в выходных данных show, чтобы найти название функции, уникальное для библиотеки.
Пример использования: PGO для ART
В этом исследовании ART используется как понятный пример, но он не отражает реальный набор библиотек, профилированных для ART, и их взаимозависимости.
Компилятор dex2oat в ART зависит от libart-compiler.so, который, в свою очередь, зависит от libart.so. Среда выполнения ART реализована в основном в файле libart.so. Контрольные показатели для компилятора и среды выполнения будут разными:
| Benchmark | Профилированные библиотеки |
|---|---|
dex2oat
|
dex2oat (исполняемый файл), libart-compiler.so, libart.so |
art_runtime
|
libart.so
|
- Добавьте следующее свойство
pgoвdex2oat,libart-compiler.so:pgo: { instrumentation: true, benchmarks: ["dex2oat",], profile_file: "dex2oat.profdata", } - Добавьте в
libart.soследующее свойствоpgo:pgo: { instrumentation: true, benchmarks: ["art_runtime", "dex2oat",], profile_file: "libart.profdata", } - Создайте сборки с инструментарием для контрольных показателей
dex2oatиart_runtime, используя:make ANDROID_PGO_INSTRUMENT=dex2oat make ANDROID_PGO_INSTRUMENT=art_runtime - Запустите тесты, чтобы проверить
dex2oatиart_runtimeи получить:- Три файла
.profrawизdex2oat(dex2oat_exe.profdata,dex2oat_libart-compiler.profdataиdexeoat_libart.profdata), идентифицированные с помощью метода, описанного в разделе Работа с файлами профилей LLVM. - Один
art_runtime_libart.profdata.
- Три файла
- Создайте общий файл profdata для исполняемого файла
dex2oatиlibart-compiler.so, используя следующую команду:llvm-profdata merge -output=dex2oat.profdata \ dex2oat_exe.profdata dex2oat_libart-compiler.profdata - Получите профиль для
libart.so, объединив профили из двух контрольных точек:llvm-profdata merge -output=libart.profdata \ dex2oat_libart.profdata art_runtime_libart.profdataНеобработанные значения
libart.soиз двух профилей могут различаться, поскольку тесты отличаются по количеству тестовых случаев и продолжительности выполнения. В этом случае можно использовать взвешенное объединение:llvm-profdata merge -output=libart.profdata \ -weighted-input=2,dex2oat_libart.profdata \ -weighted-input=1,art_runtime_libart.profdataПриведенная выше команда присваивает профилю из
dex2oatв два раза больший вес. Фактический вес определяется на основе знаний о предметной области или экспериментальным путем. - Загрузите файлы профиля
dex2oat.profdataиlibart.profdataвtoolchain/pgo-profilesдля использования во время сборки.
Вы также можете создать одну сборку с инструментарием, в которой все библиотеки будут инструментированы с помощью следующей команды:
make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime
(or)
make ANDROID_PGO_INSTRUMENT=ALLВторая команда создает все модули с поддержкой PGO для профилирования.