Система сборки Android поддерживает оптимизацию Clang на основе профилей (PGO) для собственных модулей Android, которые имеют правила сборки схемы. На этой странице описывается Clang PGO, как постоянно генерировать и обновлять профили, используемые для PGO, и как интегрировать PGO с системой сборки (с вариантами использования).
NB: В этом документе описывается использование PGO на платформе Android. Чтобы узнать об использовании PGO из приложения для Android, посетите эту страницу .
О Clang PGO
Clang может выполнять оптимизацию на основе профиля, используя два типа профилей:
- Инструментальные профили генерируются из инструментированной целевой программы. Эти профили детализированы и накладывают большие накладные расходы во время выполнения.
- Профили на основе выборки обычно создаются с помощью аппаратных счетчиков выборки. Они создают небольшие накладные расходы во время выполнения и могут быть собраны без какого-либо инструментария или модификации двоичного файла. Они менее детализированы, чем профили на основе инструментов.
Все профили должны создаваться на основе репрезентативной рабочей нагрузки, которая реализует типичное поведение приложения. В то время как Clang поддерживает как на основе AST ( -fprofile-instr-generate
), так и на основе LLVM IR ( -fprofile-generate)
, Android поддерживает только LLVM на основе IR для инструментального PGO.
Следующие флаги необходимы для сборки для сбора профилей:
-
-fprofile-generate
для инструментов на основе IR. С этой опцией серверная часть использует метод взвешенного минимального связующего дерева, чтобы уменьшить количество точек инструментирования и оптимизировать их размещение на ребрах с малым весом (используйте эту опцию также для шага ссылки). Драйвер Clang автоматически передает компоновщику среду выполнения профилирования (libclang_rt.profile- arch -android.a
). Эта библиотека содержит подпрограммы для записи профилей на диск после выхода из программы. -
-gline-tables-only
для сбора профилей на основе выборки для создания минимальной отладочной информации.
Профиль можно использовать для PGO, используя -fprofile-instr-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 и оценить его преимущества в производительности.
Чтобы указать дополнительные каталоги профилей для конкретных продуктов, добавьте их к переменной 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
Чтобы сопоставить уникальные_идентификаторы с отдельными библиотеками, найдите в выходных данных show
для каждого уникального_идентификатора имя функции, уникальное для библиотеки.
Практический пример: 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
.
- Три файла
- Создайте общий файл
dex2oat
для исполняемого файла 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 для профилирования.