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-generateuntuk 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-onlyuntuk 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-generateke 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=<>.profdatake 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
pgoke 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
pgoberikut kedex2oat,libart-compiler.so:pgo: { instrumentation: true, benchmarks: ["dex2oat",], profile_file: "dex2oat.profdata", } - Tambahkan properti
pgoberikut kelibart.so:pgo: { instrumentation: true, benchmarks: ["art_runtime", "dex2oat",], profile_file: "libart.profdata", } - Buat build berinstrumen untuk benchmark
dex2oatdanart_runtimemenggunakan:make ANDROID_PGO_INSTRUMENT=dex2oat make ANDROID_PGO_INSTRUMENT=art_runtime - Jalankan benchmark yang menggunakan
dex2oatdanart_runtimeuntuk mendapatkan:- Tiga file
.profrawdaridex2oat(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
dex2oatyang dapat dieksekusi danlibart-compiler.somenggunakan:llvm-profdata merge -output=dex2oat.profdata \ dex2oat_exe.profdata dex2oat_libart-compiler.profdata - Dapatkan profil untuk
libart.sodengan menggabungkan profil dari dua benchmark:llvm-profdata merge -output=libart.profdata \ dex2oat_libart.profdata art_runtime_libart.profdataJumlah mentah untuk
libart.sodari 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.profdataPerintah di atas menetapkan bobot dua kali lipat ke profil dari
dex2oat. Bobot sebenarnya harus ditentukan berdasarkan pengetahuan atau eksperimen domain. - Periksa file profil
dex2oat.profdatadanlibart.profdatake dalamtoolchain/pgo-profilesuntuk 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=ALLPerintah kedua mem-build semua modul yang mengaktifkan PGO untuk pembuatan profil.