Система сборки Android для Android 13 и более ранних версий поддерживает использование оптимизации на основе профиля (PGO) Clang в собственных модулях Android, имеющих правила сборки схемы . На этой странице описывается Clang PGO, как постоянно создавать и обновлять профили, используемые для PGO, и как интегрировать PGO с системой сборки (с указанием вариантов использования).
Примечание. В этом документе описывается использование PGO на платформе Android. Чтобы узнать об использовании PGO из приложения Android, посетите эту страницу .
О Кланг ПГО
Clang может выполнять оптимизацию на основе профилей, используя два типа профилей:
- Профили на основе инструментов генерируются из инструментированной целевой программы. Эти профили детализированы и требуют больших затрат времени выполнения.
- Профили на основе выборки обычно создаются аппаратными счетчиками выборки. Они требуют небольших накладных расходов во время выполнения и могут быть собраны без каких-либо инструментов или изменений в двоичном файле. Они менее детальны, чем профили, основанные на приборах.
Все профили должны создаваться на основе репрезентативной рабочей нагрузки, которая демонстрирует типичное поведение приложения. Хотя Clang поддерживает как на основе AST ( -fprofile-instr-generate
), так и на основе LLVM IR ( -fprofile-generate)
, Android поддерживает только LLVM IR для PGO на основе инструментов.
Для сборки сбора профилей необходимы следующие флаги:
-
-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 включает в себя следующие шаги:
- Создайте библиотеку/исполняемый файл с инструментами, передав
-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 и измерить его выигрыш в производительности.
Чтобы указать дополнительные каталоги профилей для конкретного продукта, добавьте их к переменной make 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 для PGO с использованием выборки. По умолчанию — 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 с отдельными библиотеками, найдите в выводе show
для каждого unique_id имя функции, уникальное для библиотеки.
Практический пример: PGO по АРТ
В тематическом исследовании АРТ представлена в качестве наглядного примера; однако это неточное описание реального набора библиотек, профилированных для ART, или их взаимозависимостей.
Предварительный компилятор dex2oat
в ART зависит от libart-compiler.so
, который, в свою очередь, зависит от libart.so
. Среда выполнения ART реализована в основном в libart.so
. Тесты для компилятора и среды выполнения будут разными:
Контрольный показатель | Профилированные библиотеки |
---|---|
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", }
- Добавьте следующее свойство
pgo
вlibart.so
: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 для профилирования.