Menggunakan Pengoptimalan Terpandu Profil (PGO)

Sistem pembangunan Android mendukung penggunaan pengoptimalan terpandu profil (PGO) Clang pada modul Android asli yang memiliki aturan pembuatan cetak biru . Halaman ini menjelaskan Dentang PGO, cara terus menghasilkan dan memperbarui profil yang digunakan untuk PGO, dan cara mengintegrasikan PGO dengan sistem build (dengan use case).

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

Tentang Dentang PGO

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

  • Profil berbasis instrumentasi dihasilkan dari program target yang diinstrumentasi. Profil ini dirinci dan memaksakan overhead runtime yang tinggi.
  • Profil berbasis pengambilan sampel biasanya diproduksi oleh penghitung perangkat keras pengambilan sampel. Mereka memaksakan overhead runtime yang rendah, dan dapat dikumpulkan tanpa instrumentasi atau modifikasi apa pun ke biner. Mereka kurang detail dibandingkan profil berbasis instrumentasi.

Semua profil harus dihasilkan dari beban kerja representatif yang menjalankan perilaku khas aplikasi. Sementara Dentang mendukung berbasis AST ( -fprofile-instr-generate ) dan berbasis IR LLVM ( -fprofile-generate) , Android hanya mendukung berbasis LLVM IR untuk PGO berbasis instrumentasi.

Bendera berikut diperlukan untuk membangun koleksi profil:

  • -fprofile-generate untuk instrumentasi berbasis IR. Dengan opsi ini, backend menggunakan pendekatan pohon rentang minimal berbobot untuk mengurangi jumlah titik instrumentasi dan mengoptimalkan penempatannya ke tepi berbobot rendah (gunakan opsi ini juga untuk langkah tautan). Driver Dentang secara otomatis meneruskan runtime 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.

Sebuah profil dapat digunakan untuk PGO menggunakan -fprofile-instr-use= pathname atau -fprofile-sample-use= pathname untuk masing-masing profil berbasis instrumentasi dan berbasis sampling.

Catatan: Saat perubahan dibuat pada kode, jika Dentang tidak dapat lagi menggunakan data profil, itu akan menghasilkan -Wprofile-instr-out-of-date .

Menggunakan PGO

Menggunakan PGO melibatkan langkah-langkah berikut:

  1. Bangun library/executable dengan instrumentasi dengan meneruskan -fprofile-generate ke compiler dan linker.
  2. Kumpulkan profil dengan menjalankan beban kerja representatif pada biner terinstrumentasi.
  3. Pascaproses 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 yang dapat direproduksi. Profil dapat digunakan saat kode berkembang, tetapi harus dibuat ulang secara berkala (atau kapan pun Clang memperingatkan bahwa profil sudah basi).

Mengumpulkan profil

Dentang dapat menggunakan profil yang dikumpulkan dengan menjalankan tolok ukur menggunakan build berinstrumen perpustakaan 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 versi berinstrumen:

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

benchmark adalah placeholder yang mengidentifikasi koleksi library yang diinstrumentasikan selama build. Input representatif yang sebenarnya (dan mungkin executable lain yang tertaut dengan perpustakaan yang sedang di-benchmark) tidak spesifik untuk PGO dan berada di luar cakupan dokumen ini.

  1. Flash atau sinkronkan build berinstrumen di 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.

Menggunakan profil selama pembuatan

Periksa profil ke dalam toolchain/pgo-profiles di pohon Android. Nama harus cocok dengan apa yang ditentukan dalam sub-properti profile_file dari properti pgo untuk perpustakaan. Sistem build 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 khusus produk tambahan, tambahkan ke variabel make PGO_ADDITIONAL_PROFILE_DIRECTORIES di BoardConfig.mk . Jika jalur tambahan ditentukan, profil di jalur ini menggantikan yang ada di toolchain/pgo-profiles .

Saat membuat gambar rilis menggunakan target dist to 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 dijatuhkan (yang secara diam-diam menonaktifkan PGO).

Mengaktifkan 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 Setel ke true untuk PGO menggunakan instrumentasi. Standarnya false .
sampling Setel ke true untuk PGO menggunakan sampling. Standarnya false .
benchmarks Daftar string. Modul ini dibuat untuk pembuatan profil jika ada tolok ukur dalam daftar yang ditentukan dalam opsi pembangunan 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 jika 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. Defaultnya true .
cflags Daftar flag tambahan untuk 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 benchmark1 dan benchmark2 menjalankan perilaku representatif untuk library libstatic1 , libstatic2 , atau libshared1 , properti pgo dari 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 secara selektif menonaktifkan PGO 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 menyelesaikan referensi ke pustaka waktu proses pembuatan profil selama pembuatan profil berbasis instrumentasi, teruskan flag build -fprofile-generate ke linker. Pustaka statis yang diinstrumentasi dengan PGO, semua pustaka bersama, dan biner apa pun yang secara langsung bergantung pada pustaka statis juga harus diinstrumentasikan untuk PGO. Namun, pustaka bersama atau executable tersebut tidak perlu menggunakan profil PGO, dan properti enable_profile_use mereka dapat disetel ke false . Di luar batasan ini, Anda dapat menerapkan PGO ke perpustakaan statis, perpustakaan bersama, atau yang dapat dieksekusi.

Menangani file profil LLVM

Mengeksekusi pustaka berinstrumen atau yang 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 pustaka 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 suatu tempat seperti /storage/emulated/0/Android/data/ packagename /files sebagai gantinya. Untuk mengubah lokasi file profil, setel 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 pohon sumber untuk digunakan selama pembuatan.

Jika beberapa binari/pustaka terinstrumentasi dimuat selama benchmark, setiap perpustakaan menghasilkan file .profraw terpisah dengan ID unik yang terpisah. Biasanya, semua file ini dapat digabungkan menjadi satu file .profdata dan digunakan untuk pembuatan PGO. Dalam kasus di mana perpustakaan dijalankan oleh tolok ukur lain, perpustakaan itu harus dioptimalkan menggunakan profil dari kedua tolok ukur tersebut. 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 s ke masing-masing perpustakaan, cari output show untuk setiap unique_id untuk nama fungsi yang unik untuk perpustakaan.

Studi Kasus: PGO untuk ART

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

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

Tolok ukur Pustaka 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 : l10n
        pgo: {
            instrumentation: true,
            benchmarks: ["dex2oat",],
            profile_file: "dex2oat.profdata",
        }
  2. Tambahkan properti pgo berikut ke libart.so : l10n
        pgo: {
            instrumentation: true,
            benchmarks: ["art_runtime", "dex2oat",],
            profile_file: "libart.profdata",
        }
  3. Buat build berinstrumen untuk tolok ukur dex2oat dan art_runtime menggunakan:
        make ANDROID_PGO_INSTRUMENT=dex2oat
        make ANDROID_PGO_INSTRUMENT=art_runtime
  4. Atau, buat build berinstrumen tunggal dengan semua pustaka yang diinstrumentasi 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 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 dapat dieksekusi dan libart-compiler.so menggunakan: l10n
    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 untuk libart.so dari dua profil mungkin berbeda karena tolok ukurnya berbeda dalam jumlah kasus uji dan durasi yang mereka jalankan. Dalam hal ini, Anda dapat menggunakan gabungan berbobot:

    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.