Sistem build Android untuk Android 13 dan yang lebih rendah mendukung penggunaan pengoptimalan terpandu profil (PGO) Clang pada modul Android native yang memiliki aturan build blueprint. Halaman ini menjelaskan Clang PGO, cara terus membuat dan memperbarui profil yang digunakan untuk PGO, dan cara mengintegrasikan PGO dengan sistem build (dengan kasus penggunaan).
Catatan: Dokumen ini menjelaskan penggunaan PGO di platform Android. Untuk mempelajari cara menggunakan PGO dari aplikasi Android, buka halaman ini.
Tentang Clang PGO
Clang dapat melakukan pengoptimalan yang dipandu profil menggunakan dua jenis profil:
- Profil berbasis instrumentasi dibuat dari program target berinstrumen. Profil ini mendetail dan menimbulkan overhead runtime yang tinggi.
- Profil berbasis sampling biasanya dihasilkan oleh sampler penghitung hardware. Pengukuran ini menimbulkan overhead runtime yang rendah, dan dapat dikumpulkan tanpa instrumentasi atau modifikasi apa pun pada biner. Profil ini kurang mendetail dibandingkan profil berbasis instrumentasi.
Semua profil harus dibuat dari beban kerja perwakilan yang
menjalankan perilaku umum aplikasi. Meskipun Clang mendukung
berbasis AST (-fprofile-instr-generate
) dan berbasis LLVM IR
(-fprofile-generate)
, Android hanya mendukung berbasis LLVM IR untuk
PGO berbasis instrumentasi.
Flag berikut diperlukan untuk membuat koleksi profil:
-fprofile-generate
untuk instrumentasi berbasis IR. Dengan opsi ini, backend menggunakan pendekatan weighted minimal spanning tree untuk mengurangi jumlah titik instrumentasi dan mengoptimalkan penempatannya ke tepi berbobot rendah (gunakan juga opsi ini untuk langkah penautan). Driver Clang secara otomatis meneruskan runtime pembuatan profil (libclang_rt.profile-arch-android.a
) ke penaut. Library ini berisi rutinitas untuk menulis profil ke disk saat program keluar.-gline-tables-only
untuk pengumpulan profil berbasis sampling guna menghasilkan informasi debug minimal.
Profil dapat digunakan untuk PGO menggunakan
-fprofile-use=pathname
atau
-fprofile-sample-use=pathname
untuk profil berbasis instrumentasi
dan berbasis sampling.
Catatan: Saat perubahan dilakukan pada kode, jika Clang tidak dapat
lagi menggunakan data profil, kode tersebut akan menghasilkan
peringatan -Wprofile-instr-out-of-date
.
Menggunakan PGO
Penggunaan PGO melibatkan langkah-langkah berikut:
- Build library/file yang dapat dieksekusi dengan instrumentasi dengan meneruskan
-fprofile-generate
ke compiler dan penaut. - Kumpulkan profil dengan menjalankan beban kerja representatif pada biner berinstrumen.
- Lanjutkan pemrosesan profil menggunakan utilitas
llvm-profdata
(untuk mengetahui detailnya, lihat Menangani file profil LLVM). - Gunakan profil untuk menerapkan PGO dengan meneruskan
-fprofile-use=<>.profdata
ke compiler dan linker.
Untuk PGO di Android, profil harus dikumpulkan secara offline dan diperiksa bersama kode untuk memastikan build yang dapat direproduksi. Profil dapat digunakan saat kode berkembang, tetapi harus dibuat ulang secara berkala (atau setiap kali Clang memperingatkan bahwa profil sudah tidak berlaku).
Mengumpulkan profil
Clang dapat menggunakan profil yang dikumpulkan dengan menjalankan benchmark menggunakan build berinstrumen library atau dengan mengambil sampel penghitung hardware saat benchmark dijalankan. Saat ini, Android tidak mendukung penggunaan pengumpulan profil berbasis sampling, sehingga Anda harus mengumpulkan profil menggunakan build berinstrumen:
- Identifikasi benchmark dan kumpulan library yang secara kolektif digunakan oleh benchmark tersebut.
- Tambahkan properti
pgo
ke benchmark dan library (detail di bawah). - Buat build Android dengan salinan berinstrumen dari library ini
menggunakan:
make ANDROID_PGO_INSTRUMENT=benchmark
benchmark
adalah placeholder yang mengidentifikasi
kumpulan library yang diinstrumentasi selama build. Input perwakilan
yang sebenarnya (dan mungkin file yang dapat dieksekusi lainnya yang ditautkan ke library yang
diukur) tidak khusus untuk PGO dan berada di luar cakupan
dokumen ini.
- Flash atau sinkronkan build berinstrumen di perangkat.
- Jalankan benchmark untuk mengumpulkan profil.
- Gunakan alat
llvm-profdata
(dibahas di bawah) untuk memproses ulang profil dan membuatnya siap untuk diperiksa ke dalam hierarki sumber.
Menggunakan profil selama build
Periksa profil ke toolchain/pgo-profiles
dalam hierarki
Android. Nama harus cocok dengan yang ditentukan dalam
sub-properti profile_file
dari properti pgo
untuk
library. Sistem build otomatis meneruskan file profil ke Clang
saat mem-build library. Variabel lingkungan ANDROID_PGO_DISABLE_PROFILE_USE
dapat ditetapkan ke true
untuk
menonaktifkan PGO untuk sementara dan mengukur manfaat performanya.
Untuk menentukan direktori profil khusus produk tambahan, tambahkan direktori tersebut ke
variabel pembuatan PGO_ADDITIONAL_PROFILE_DIRECTORIES
di
BoardConfig.mk
. Jika jalur tambahan ditentukan, profil di
jalur ini akan menggantikan profil di toolchain/pgo-profiles
.
Saat membuat image rilis menggunakan target dist
ke
make
, sistem build akan menulis nama file profil yang hilang
ke $DIST_DIR/pgo_profile_file_missing.txt
. Anda dapat memeriksa file
ini untuk melihat file profil yang tidak sengaja dihapus (yang secara senyap
menonaktifkan PGO).
Mengaktifkan PGO dalam file Android.bp
Untuk mengaktifkan PGO dalam file Android.bp
untuk modul native, cukup
tentukan properti pgo
. Properti ini memiliki sub-properti
berikut:
Properti | Deskripsi |
---|---|
instrumentation
|
Tetapkan ke true untuk PGO menggunakan instrumentasi. Default-nya adalah
false . |
sampling
|
Tetapkan ke true untuk PGO menggunakan sampling. Default-nya adalah
false . |
benchmarks
|
Daftar string. Modul ini dibuat untuk pembuatan profil jika benchmark
dalam daftar ditentukan dalam opsi build
ANDROID_PGO_INSTRUMENT . |
profile_file
|
File profil (relatif terhadap toolchain/pgo-profile ) untuk digunakan
dengan PGO. Build memperingatkan bahwa file ini tidak ada dengan menambahkan file
ini ke $DIST_DIR/pgo_profile_file_missing.txt
kecuali properti enable_profile_use ditetapkan ke
false ATAU
variabel build ANDROID_PGO_NO_PROFILE_USE ditetapkan ke
true . |
enable_profile_use
|
Tetapkan ke false jika profil tidak boleh digunakan selama
build. Dapat digunakan selama bootstrap untuk mengaktifkan pengumpulan profil atau untuk
menonaktifkan PGO untuk sementara. Default-nya adalah true . |
cflags
|
Daftar flag tambahan yang akan digunakan selama build berinstrumen. |
Contoh modul dengan 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", } }
Jika benchmark benchmark1
dan benchmark2
menjalankan perilaku perwakilan untuk library libstatic1
,
libstatic2
, atau libshared1
, properti pgo
library ini juga dapat menyertakan benchmark. Modul
defaults
di Android.bp
dapat menyertakan spesifikasi
pgo
umum untuk sekumpulan library guna menghindari pengulangan
aturan build yang sama untuk beberapa modul.
Untuk memilih file profil yang berbeda atau menonaktifkan PGO secara selektif untuk
arsitektur, tentukan properti profile_file
,
enable_profile_use
, dan cflags
per
arsitektur. Contoh (dengan target arsitektur dalam
cetak tebal):
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", } } } }
Untuk me-resolve referensi ke library runtime pembuatan profil selama
pembuatan profil berbasis instrumentasi, teruskan flag build
-fprofile-generate
ke penaut. Library statis yang diinstrumentasikan
dengan PGO, semua library bersama, dan biner apa pun yang secara langsung bergantung pada
library statis juga harus diinstrumentasikan untuk PGO. Namun, library bersama
atau file yang dapat dieksekusi tersebut tidak perlu menggunakan profil PGO, dan properti
enable_profile_use
-nya dapat ditetapkan ke false
.
Di luar batasan ini, Anda dapat menerapkan PGO ke library statis, library
bersama, atau file yang dapat dieksekusi.
Menangani file profil LLVM
Menjalankan library berinstrumen atau file yang dapat dieksekusi akan menghasilkan file profil
bernama default_unique_id_0.profraw
di
/data/local/tmp
(dengan unique_id
adalah
hash numerik yang unik untuk library ini). Jika file ini sudah ada,
runtime pembuatan profil akan menggabungkan profil baru dengan profil lama saat menulis
profil. Perhatikan bahwa /data/local/tmp
tidak dapat diakses oleh developer
aplikasi; mereka harus menggunakan tempat seperti
/storage/emulated/0/Android/data/packagename/files
.
Untuk mengubah lokasi file profil, tetapkan variabel lingkungan LLVM_PROFILE_FILE
saat runtime.
Utilitas llvm-profdata
kemudian digunakan untuk mengonversi file .profraw
(dan mungkin
menggabungkan beberapa file .profraw
) ke file
.profdata
:
llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>
profile.profdata
kemudian dapat diperiksa ke dalam hierarki
sumber untuk digunakan selama build.
Jika beberapa biner/library berinstrumen dimuat selama benchmark,
setiap library akan menghasilkan file .profraw
terpisah dengan ID unik
terpisah. Biasanya, semua file ini dapat digabungkan ke dalam satu
file .profdata
dan digunakan untuk build PGO. Jika library
dijalankan oleh benchmark lain, library tersebut harus dioptimalkan menggunakan
profil dari kedua benchmark. Dalam situasi ini, opsi show
dari llvm-profdata
berguna:
llvm-profdata merge -output=default_unique_id.profdata default_unique_id_0.profraw llvm-profdata show -all-functions default_unique_id.profdata
Untuk memetakan unique_id ke setiap library, telusuri output show
untuk setiap unique_id guna menemukan nama fungsi yang unik untuk library.
Studi kasus: PGO untuk ART
Studi kasus ini menyajikan ART sebagai contoh yang relevan; namun, studi kasus ini bukan deskripsi akurat dari kumpulan library sebenarnya yang dibuat profilnya untuk ART atau interdependensi library tersebut.
Compiler ahead-of-time dex2oat
di ART bergantung pada
libart-compiler.so
, yang kemudian bergantung pada
libart.so
. Runtime ART diimplementasikan terutama di
libart.so
. Benchmark untuk compiler dan runtime akan
berbeda:
Benchmark | Library yang dibuat profilnya |
---|---|
dex2oat
|
dex2oat (dapat dieksekusi), libart-compiler.so ,
libart.so |
art_runtime
|
libart.so
|
- Tambahkan properti
pgo
berikut kedex2oat
,libart-compiler.so
:pgo: { instrumentation: true, benchmarks: ["dex2oat",], profile_file: "dex2oat.profdata", }
- Tambahkan properti
pgo
berikut kelibart.so
:pgo: { instrumentation: true, benchmarks: ["art_runtime", "dex2oat",], profile_file: "libart.profdata", }
- Buat build berinstrumen untuk benchmark
dex2oat
danart_runtime
menggunakan:make ANDROID_PGO_INSTRUMENT=dex2oat make ANDROID_PGO_INSTRUMENT=art_runtime
- Jalankan benchmark yang menggunakan
dex2oat
danart_runtime
untuk mendapatkan:- Tiga file
.profraw
daridex2oat
(dex2oat_exe.profdata
,dex2oat_libart-compiler.profdata
, dandexeoat_libart.profdata
), diidentifikasi menggunakan metode yang dijelaskan dalam Menangani file profil LLVM. - Satu
art_runtime_libart.profdata
.
- Tiga file
- Buat file profdata umum untuk
dex2oat
yang dapat dieksekusi danlibart-compiler.so
menggunakan:llvm-profdata merge -output=dex2oat.profdata \ dex2oat_exe.profdata dex2oat_libart-compiler.profdata
- Dapatkan profil untuk
libart.so
dengan menggabungkan profil dari dua benchmark:llvm-profdata merge -output=libart.profdata \ dex2oat_libart.profdata art_runtime_libart.profdata
Jumlah mentah untuk
libart.so
dari kedua profil mungkin berbeda karena benchmark berbeda dalam jumlah kasus pengujian dan durasi yang dijalankan. Dalam hal ini, Anda dapat menggunakan penggabungan berbobot:llvm-profdata merge -output=libart.profdata \ -weighted-input=2,dex2oat_libart.profdata \ -weighted-input=1,art_runtime_libart.profdata
Perintah di atas menetapkan bobot dua kali lipat ke profil dari
dex2oat
. Bobot sebenarnya harus ditentukan berdasarkan pengetahuan atau eksperimen domain. - Periksa file profil
dex2oat.profdata
danlibart.profdata
ke dalamtoolchain/pgo-profiles
untuk digunakan selama build.
Atau, buat satu build berinstrumen dengan semua library yang diinstrumentasikan menggunakan:
make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime (or) make ANDROID_PGO_INSTRUMENT=ALL
Perintah kedua mem-build semua modul yang mengaktifkan PGO untuk pembuatan profil.