Gunakan pengoptimalan yang dipandu profil

Sistem build Android untuk Android 13 dan yang lebih rendah mendukung penggunaan pengoptimalan terpandu profil (PGO) Clang pada modul Android asli yang memiliki aturan build cetak biru . 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).

NB: Dokumen ini menjelaskan penggunaan PGO di platform Android. Untuk mempelajari cara menggunakan PGO dari aplikasi Android, kunjungi halaman ini .

Tentang Dentang PGO

Clang dapat melakukan pengoptimalan yang dipandu profil menggunakan dua jenis profil:

  • Profil berbasis instrumentasi dihasilkan dari program target yang diinstrumentasi. Profil ini dirinci dan memerlukan overhead waktu proses yang tinggi.
  • Profil berbasis pengambilan sampel biasanya dihasilkan dengan pengambilan sampel penghitung perangkat keras. Mereka menerapkan overhead runtime yang rendah, dan dapat dikumpulkan tanpa instrumentasi atau modifikasi apa pun pada biner. Profil tersebut kurang detail dibandingkan profil berbasis instrumentasi.

Semua profil harus dihasilkan dari beban kerja representatif yang menerapkan perilaku umum aplikasi. Meskipun Clang mendukung berbasis AST ( -fprofile-instr-generate ) dan berbasis LLVM IR ( -fprofile-generate) , Android hanya mendukung LLVM berbasis IR untuk PGO berbasis instrumentasi.

Tanda-tanda berikut diperlukan untuk membangun pengumpulan profil:

  • -fprofile-generate untuk instrumentasi berbasis IR. Dengan opsi ini, backend menggunakan pendekatan pohon merentang minimal berbobot untuk mengurangi jumlah titik instrumentasi dan mengoptimalkan penempatannya ke tepi berbobot rendah (gunakan juga opsi ini untuk langkah tautan). Driver Clang secara otomatis meneruskan waktu proses pembuatan profil ( libclang_rt.profile- arch -android.a ) ke linker. Pustaka ini berisi rutinitas untuk menulis profil ke disk saat program keluar.
  • -gline-tables-only untuk pengumpulan profil berbasis pengambilan sampel untuk menghasilkan informasi debug minimal.

Profil dapat digunakan untuk PGO menggunakan -fprofile-use= pathname atau -fprofile-sample-use= pathname masing-masing untuk profil berbasis instrumentasi dan berbasis pengambilan sampel.

Catatan: Saat perubahan dilakukan pada kode, jika Clang tidak dapat lagi menggunakan data profil, maka akan muncul peringatan -Wprofile-instr-out-of-date .

Gunakan PGO

Menggunakan PGO melibatkan langkah-langkah berikut:

  1. Bangun perpustakaan/dapat dieksekusi dengan instrumentasi dengan meneruskan -fprofile-generate ke compiler dan linker.
  2. Kumpulkan profil dengan menjalankan beban kerja representatif pada biner yang diinstrumentasi.
  3. Pasca-proses profil menggunakan utilitas llvm-profdata (untuk detailnya, lihat Menangani file profil LLVM ).
  4. 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 dapat direproduksi. Profil dapat digunakan seiring perkembangan kode, namun harus dibuat ulang secara berkala (atau setiap kali Clang memperingatkan bahwa profil sudah basi).

Kumpulkan profil

Dentang dapat menggunakan profil yang dikumpulkan dengan menjalankan tolok ukur menggunakan build pustaka yang diinstrumentasikan atau dengan mengambil sampel penghitung perangkat keras saat tolok ukur dijalankan. Saat ini, Android tidak mendukung penggunaan pengumpulan profil berbasis pengambilan sampel, jadi Anda harus mengumpulkan profil menggunakan build berinstrumen:

  1. Identifikasi tolok ukur dan kumpulan pustaka yang secara kolektif digunakan oleh tolok ukur tersebut.
  2. Tambahkan properti pgo ke benchmark dan perpustakaan (detailnya di bawah).
  3. Buat build Android dengan salinan instrumen dari pustaka ini menggunakan:
    make ANDROID_PGO_INSTRUMENT=benchmark

benchmark adalah placeholder yang mengidentifikasi koleksi perpustakaan yang diinstrumentasikan selama pembangunan. Input representatif sebenarnya (dan mungkin executable lain yang tertaut ke perpustakaan yang dijadikan tolok ukur) tidak spesifik untuk PGO dan berada di luar cakupan dokumen ini.

  1. Flash atau sinkronkan build yang diinstrumentasi pada perangkat.
  2. Jalankan benchmark untuk mengumpulkan profil.
  3. Gunakan alat llvm-profdata (dibahas di bawah) untuk pasca-proses profil dan membuatnya siap untuk diperiksa ke dalam pohon sumber.

Gunakan profil selama pembuatan

Periksa profil ke dalam toolchain/pgo-profiles di pohon Android. Nama harus sesuai dengan apa yang ditentukan dalam sub-properti profile_file dari properti pgo untuk perpustakaan. Sistem pembangunan secara otomatis meneruskan file profil ke Dentang saat membangun perpustakaan. Variabel lingkungan ANDROID_PGO_DISABLE_PROFILE_USE dapat disetel ke true untuk menonaktifkan PGO sementara dan mengukur manfaat kinerjanya.

Untuk menentukan direktori profil spesifik produk tambahan, tambahkan direktori tersebut ke variabel make PGO_ADDITIONAL_PROFILE_DIRECTORIES dalam BoardConfig.mk . Jika jalur tambahan ditentukan, profil di jalur ini akan menggantikan jalur yang ada di toolchain/pgo-profiles .

Saat membuat gambar rilis menggunakan target dist ke make , sistem build menulis nama file profil yang hilang ke $DIST_DIR/pgo_profile_file_missing.txt . Anda dapat memeriksa file ini untuk melihat file profil apa yang tidak sengaja terjatuh (yang secara diam-diam menonaktifkan PGO).

Aktifkan PGO di file Android.bp

Untuk mengaktifkan PGO di file Android.bp untuk modul asli, cukup tentukan properti pgo . Properti ini memiliki sub-properti berikut:

Properti Keterangan
instrumentation Ditetapkan ke true untuk PGO menggunakan instrumentasi. Standarnya false .
sampling Ditetapkan ke true untuk PGO menggunakan pengambilan sampel. Standarnya false .
benchmarks Daftar string. Modul ini dibuat untuk pembuatan profil jika ada tolok ukur dalam daftar yang 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 disetel ke false ATAU variabel build ANDROID_PGO_NO_PROFILE_USE disetel ke true .
enable_profile_use Setel ke false jika profil tidak boleh digunakan selama pembuatan. Dapat digunakan selama bootstrap untuk mengaktifkan pengumpulan profil atau untuk menonaktifkan PGO sementara. Standarnya adalah true .
cflags Daftar tanda tambahan untuk digunakan selama pembuatan instrumen.

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 menerapkan perilaku yang mewakili perpustakaan libstatic1 , libstatic2 , atau libshared1 , properti pgo dari perpustakaan ini juga dapat menyertakan benchmark. Modul defaults di Android.bp dapat menyertakan spesifikasi pgo umum untuk sekumpulan pustaka guna menghindari pengulangan aturan build yang sama untuk beberapa modul.

Untuk memilih file profil yang berbeda atau menonaktifkan PGO secara selektif untuk suatu arsitektur, tentukan properti profile_file , enable_profile_use , dan cflags per arsitektur. Contoh (dengan target arsitektur dicetak 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 mengatasi referensi ke pustaka runtime pembuatan profil selama pembuatan profil berbasis instrumentasi, teruskan flag build -fprofile-generate ke linker. Perpustakaan statis yang diinstrumentasi dengan PGO, semua perpustakaan bersama, dan biner apa pun yang secara langsung bergantung pada perpustakaan statis juga harus diinstrumentasi untuk PGO. Namun, pustaka bersama atau file yang dapat dieksekusi tersebut tidak perlu menggunakan profil PGO, dan properti enable_profile_use dapat disetel ke false . Di luar batasan ini, Anda dapat menerapkan PGO ke perpustakaan statis, perpustakaan bersama, atau perpustakaan apa pun yang dapat dieksekusi.

Menangani file profil LLVM

Mengeksekusi perpustakaan yang diinstrumentasi atau dapat dieksekusi menghasilkan file profil bernama default_ unique_id _0.profraw di /data/local/tmp (di mana unique_id adalah hash numerik yang unik untuk perpustakaan ini). Jika file ini sudah ada, runtime pembuatan profil akan menggabungkan profil baru dengan yang lama saat menulis profil. Perhatikan bahwa /data/local/tmp tidak dapat diakses oleh pengembang aplikasi; mereka harus menggunakan tempat seperti /storage/emulated/0/Android/data/ packagename /files sebagai gantinya. Untuk mengubah lokasi file profil, atur variabel lingkungan LLVM_PROFILE_FILE saat runtime.

Utilitas llvm-profdata kemudian digunakan untuk mengonversi file .profraw (dan mungkin menggabungkan beberapa file .profraw ) menjadi file .profdata :

  llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>

profile.profdata kemudian dapat diperiksa ke dalam pohon sumber untuk digunakan selama pembangunan.

Jika beberapa binari/pustaka yang diinstrumentasikan dimuat selama benchmark, setiap pustaka akan menghasilkan file .profraw terpisah dengan ID unik terpisah. Biasanya, semua file ini dapat digabungkan menjadi satu file .profdata dan digunakan untuk pembuatan PGO. Jika suatu pustaka dijalankan dengan tolok ukur lain, pustaka tersebut harus dioptimalkan menggunakan profil dari kedua tolok ukur tersebut. Dalam situasi ini, opsi show 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 perpustakaan individual, cari output show untuk setiap Unique_id untuk nama fungsi yang unik untuk perpustakaan.

Studi kasus: PGO untuk ART

Studi kasus ini menyajikan ART sebagai contoh yang relevan; namun, ini bukan deskripsi akurat tentang kumpulan perpustakaan sebenarnya yang diprofilkan untuk ART atau saling ketergantungannya.

Kompiler dex2oat sebelumnya di ART bergantung pada libart-compiler.so , yang selanjutnya bergantung pada libart.so . Runtime ART diimplementasikan terutama di libart.so . Tolok ukur untuk compiler dan runtime akan berbeda:

Tolok ukur Perpustakaan yang diprofilkan
dex2oat dex2oat (dapat dieksekusi), libart-compiler.so , libart.so
art_runtime libart.so
  1. Tambahkan properti pgo berikut ke dex2oat , libart-compiler.so :
        pgo: {
            instrumentation: true,
            benchmarks: ["dex2oat",],
            profile_file: "dex2oat.profdata",
        }
  2. Tambahkan properti pgo berikut ke libart.so :
        pgo: {
            instrumentation: true,
            benchmarks: ["art_runtime", "dex2oat",],
            profile_file: "libart.profdata",
        }
  3. Buat build berinstrumen untuk benchmark dex2oat dan art_runtime menggunakan:
        make ANDROID_PGO_INSTRUMENT=dex2oat
        make ANDROID_PGO_INSTRUMENT=art_runtime
  4. Alternatifnya, buat satu build berinstrumen dengan semua pustaka diinstrumentasikan menggunakan:

        make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime
        (or)
        make ANDROID_PGO_INSTRUMENT=ALL

    Perintah kedua membangun semua modul yang mendukung PGO untuk pembuatan profil.

  5. Jalankan benchmark dengan menggunakan dex2oat dan art_runtime untuk mendapatkan:
    • Tiga file .profraw dari dex2oat ( dex2oat_exe.profdata , dex2oat_libart-compiler.profdata , dan dexeoat_libart.profdata ), diidentifikasi menggunakan metode yang dijelaskan dalam Menangani file profil LLVM .
    • Satu art_runtime_libart.profdata .
  6. Hasilkan file profdata umum untuk dex2oat yang dapat dieksekusi dan libart-compiler.so menggunakan:
    llvm-profdata merge -output=dex2oat.profdata \
        dex2oat_exe.profdata dex2oat_libart-compiler.profdata
  7. Dapatkan profil untuk libart.so dengan menggabungkan profil dari dua tolok ukur:
    llvm-profdata merge -output=libart.profdata \
        dex2oat_libart.profdata art_runtime_libart.profdata

    Jumlah mentah libart.so dari kedua profil mungkin berbeda karena tolok ukurnya berbeda dalam jumlah kasus pengujian dan durasi dijalankannya. Dalam hal ini, Anda dapat menggunakan gabungan tertimbang:

    llvm-profdata merge -output=libart.profdata \
        -weighted-input=2,dex2oat_libart.profdata \
        -weighted-input=1,art_runtime_libart.profdata

    Perintah di atas memberikan bobot dua kali lipat ke profil dari dex2oat . Bobot sebenarnya harus ditentukan berdasarkan pengetahuan domain atau eksperimen.

  8. Periksa file profil dex2oat.profdata dan libart.profdata ke dalam toolchain/pgo-profiles untuk digunakan selama pembuatan.