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.