Gunakan pengoptimalan yang dipandu profil

Sistem build Android untuk Android 13 dan yang lebih rendah mendukung penggunaan panduan profil dari Clang pengoptimalan (PGO) di modul Android native yang memiliki build blueprint aturan. Halaman ini menjelaskan PGO Clang, cara membuat dan mengupdate secara berkelanjutan 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 tentang PGO dari aplikasi Android, buka halaman ini.

Tentang PGO Clang

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

  • Profil berbasis instrumentasi dibuat dari program target berinstrumen. Profil ini rinci dan memberlakukan overhead runtime.
  • Profil berbasis pengambilan sampel biasanya dibuat oleh konter perangkat keras. Mereka mengenakan overhead {i>runtime<i} yang rendah, dan dapat dikumpulkan tanpa instrumentasi atau modifikasi apa pun pada biner. Mereka kurang detail dibandingkan profil berbasis instrumentasi.

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

Tanda berikut diperlukan guna membangun untuk koleksi profil:

  • -fprofile-generate untuk instrumentasi berbasis IR. Dengan ini , backend menggunakan pendekatan pohon rentang minimal berbobot untuk mengurangi jumlah titik instrumentasi dan mengoptimalkan penempatannya untuk tepian yang kurang tebal (gunakan juga opsi ini untuk langkah penautan). Clang driver akan 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 pengambilan sampel untuk menghasilkan sedikit informasi proses debug.

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

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

Gunakan PGO

Penggunaan PGO melibatkan langkah-langkah berikut:

  1. Membangun library/yang dapat dieksekusi dengan instrumentasi dengan meneruskan -fprofile-generate ke compiler dan linker.
  2. Kumpulkan profil dengan menjalankan beban kerja representatif di biner berinstrumen.
  3. Lakukan pascaproses pada profil menggunakan utilitas llvm-profdata (untuk mengetahui detailnya, lihat Menangani LLVM file profil).
  4. Gunakan profil untuk menerapkan PGO dengan meneruskan -fprofile-use=<>.profdata ke compiler dan penaut.

Untuk PGO di Android, profil harus dikumpulkan secara offline dan check in di samping kode untuk memastikan build yang dapat direproduksi. Profil tersebut dapat digunakan sebagai kode berkembang, tetapi harus dibuat ulang secara berkala (atau setiap kali Clang memberikan peringatan bahwa profil sudah usang).

Mengumpulkan profil

Clang dapat menggunakan profil yang dikumpulkan dengan menjalankan benchmark menggunakan library berinstrumen atau dengan mengambil sampel penghitung perangkat keras saat tolok ukur dijalankan. Saat ini, Android belum mendukung penggunaan berbasis pengambilan sampel kumpulan profil, jadi Anda harus mengumpulkan profil menggunakan bangun:

  1. Mengidentifikasi benchmark dan kumpulan library yang secara kolektif dijalankan oleh {i>benchmark<i} itu.
  2. Menambahkan properti pgo ke benchmark dan library (detail di bawah).
  3. Membuat build Android dengan salinan berinstrumen library ini menggunakan:
    make ANDROID_PGO_INSTRUMENT=benchmark

benchmark adalah placeholder yang mengidentifikasi koleksi library yang diinstrumentasikan selama build. Perwakilan yang sebenarnya {i>input<i} (dan mungkin {i>executable<i} lainnya yang terhubung dengan {i>library<i} yang diukur) tidak spesifik untuk PGO dan berada di luar cakupan ini dokumen.

  1. Lakukan flash atau sinkronkan build berinstrumen pada perangkat.
  2. Jalankan benchmark untuk mengumpulkan profil.
  3. Menggunakan alat llvm-profdata (dibahas di bawah) untuk pascaproses profil dan membuatnya siap untuk diperiksa ke sumbernya hierarki.

Menggunakan profil selama membangun

Periksa profil ke toolchain/pgo-profiles di Android hierarki. Nama harus sesuai dengan yang ditetapkan dalam profile_file sub-properti dari properti pgo untuk perpustakaan. Sistem build secara otomatis meneruskan file profil ke Clang saat membangun library. ANDROID_PGO_DISABLE_PROFILE_USE variabel lingkungan 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 make PGO_ADDITIONAL_PROFILE_DIRECTORIES dalam BoardConfig.mk. Jika jalur tambahan ditentukan, profil dalam jalur ini akan menggantikan jalur di toolchain/pgo-profiles.

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

Mengaktifkan PGO di file Android.bp

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

Properti Deskripsi
instrumentation Tetapkan ke true untuk PGO menggunakan instrumentasi. Defaultnya adalah false.
sampling Tetapkan ke true untuk PGO menggunakan pengambilan sampel. Defaultnya adalah false.
benchmarks Daftar string. Modul ini dibuat untuk pembuatan profil jika ada tolok ukur dalam daftar ditentukan dalam build ANDROID_PGO_INSTRUMENT sebelumnya.
profile_file File profil (relatif terhadap toolchain/pgo-profile) yang akan digunakan dengan PGO. Build memperingatkan bahwa file ini tidak ada dengan menambahkan ini file 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 Tetapkan ke false jika profil tidak boleh digunakan selama buat. Dapat digunakan selama bootstrap untuk mengaktifkan pengumpulan profil atau untuk untuk sementara menonaktifkan PGO. Defaultnya adalah true.
cflags Daftar tanda 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 perilaku representatif latihan untuk library libstatic1, libstatic2, atau libshared1, pgo library ini juga dapat menyertakan benchmark. Tujuan Modul defaults di Android.bp dapat mencakup atribut Spesifikasi pgo 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 tertentu, tentukan profile_file, enable_profile_use, dan cflags properti per tentang arsitektur ini. Contoh (dengan target arsitektur di 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, meneruskan flag build -fprofile-generate ke linker. Library statis berinstrumen dengan PGO, semua pustaka bersama, dan biner apa pun yang secara langsung bergantung pada library statis juga harus diinstrumentasikan untuk PGO. Namun, {i>library<i} atau {i>executable<i} tidak perlu menggunakan profil PGO, dan Properti enable_profile_use dapat ditetapkan ke false. Di luar batasan ini, Anda dapat menerapkan PGO ke library statis apa pun, {i>library<i}, atau {i>executable<i}.

Menangani file profil LLVM

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

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

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

profile.profdata kemudian dapat di-check in ke sumbernya untuk digunakan selama build.

Jika beberapa biner/library berinstrumen dimuat selama benchmark, setiap library akan menghasilkan file .profraw terpisah dengan ID unik. Biasanya, semua file ini dapat digabungkan menjadi satu File .profdata dan digunakan untuk build PGO. Dalam kasus di mana library dijalankan oleh benchmark lain, library tersebut harus dioptimalkan menggunakan profil dari kedua benchmark tersebut. Dalam situasi ini, show opsi 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 library individual, telusuri Output show untuk setiap unique_id untuk nama fungsi yang bersifat unik untuk library.

Studi kasus: PGO untuk ART

Studi kasus ini menyajikan ART sebagai contoh yang relevan; Namun, bukanlah deskripsi yang akurat dari kumpulan pustaka aktual yang dibuat untuk ART atau interdependensi mereka.

Compiler awal dex2oat di ART bergantung pada libart-compiler.so, yang selanjutnya bergantung pada libart.so. Waktu proses ART diimplementasikan terutama di libart.so. Benchmark untuk compiler dan runtime akan berbeda:

Benchmark Library profil
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. Membuat build berinstrumen untuk dex2oat dan Benchmark art_runtime menggunakan:
        make ANDROID_PGO_INSTRUMENT=dex2oat
        make ANDROID_PGO_INSTRUMENT=art_runtime
  4. Atau, buat build berinstrumen tunggal dengan semua library 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 Anda.

  5. Jalankan benchmark yang menjalankan dex2oat dan art_runtime untuk mendapatkan:
    • Tiga file .profraw dari dex2oat (dex2oat_exe.profdata, dex2oat_libart-compiler.profdata, dan dexeoat_libart.profdata), yang diidentifikasi menggunakan metode dijelaskan dalam Menangani profil LLVM file.
    • Satu art_runtime_libart.profdata.
  6. Buat file profdata umum untuk file 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 {i>benchmark<i}:
    llvm-profdata merge -output=libart.profdata \
        dex2oat_libart.profdata art_runtime_libart.profdata

    Jumlah mentah untuk libart.so dari kedua profil mungkin tidak sama karena tolok ukurnya berbeda dalam jumlah kasus pengujian dan dari durasi waktu yang mana mereka berjalan. 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 dua kali bobot pada profil dari dex2oat. Berat sebenarnya harus ditentukan berdasarkan domain pengetahuan atau eksperimen.

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