File urutan adalah teknik pengoptimalan penaut terbaru. File urutan ini adalah file teks yang berisi simbol yang menampilkan fungsi. Penaut seperti lld menggunakan file urutan untuk membuat tata letak fungsi dalam urutan tertentu. Biner atau library dengan simbol yang diurutkan ini mengurangi kesalahan halaman dan mengoptimalkan waktu peluncuran program karena pemuatan simbol yang efisien selama cold start program.
Fitur file urutan dapat ditambahkan ke aplikasi Anda dengan mengikuti tiga langkah berikut:
- Membuat profil dan file pemetaan
- Membuat file urutan dari profil dan file pemetaan
- Menggunakan file urutan selama build Rilis untuk membuat tata letak simbol
Membuat File Urutan
Membuat file urutan memerlukan tiga langkah:
- Membangun versi berinstrumen aplikasi yang menulis file urutan
- Menjalankan aplikasi untuk membuat profil
- Melanjutkan pemrosesan profil dan file pemetaan
Membuat Build Berinstrumen
Profil dibuat dengan menjalankan build berinstrumen aplikasi.
Build berinstrumen memerlukan penambahan -forder-file-instrumentation
ke
tanda compiler dan penaut dengan
-mllvm -orderfile-write-mapping=<filename>-mapping.txt
yang ditambahkan secara khusus ke tanda compiler.
Tanda instrumentasi memungkinkan instrumentasi file urutan untuk pembuatan profil dan
memuat library tertentu yang diperlukan untuk pembuatan profil.
Di sisi lain, tanda pemetaan hanya menghasilkan file pemetaan yang menunjukkan
hash MD5 untuk setiap fungsi dalam biner atau library.
Selain itu, pastikan untuk meneruskan tanda pengoptimalan apa pun kecuali -O0
, karena
tanda instrumentasi dan tanda pemetaan memerlukannya.
Jika tidak ada tanda pengoptimalan yang diteruskan, file pemetaan tidak akan dibuat dan
build berinstrumen mungkin menghasilkan hash yang salah ke file profil.
ndk-build
Pastikan untuk membangun aplikasi dengan APP_OPTIM=release
agar ndk-build menggunakan mode
pengoptimalan selain -O0
. Jika membangun aplikasi dengan AGP, perilaku ini akan otomatis diterapkan untuk build
rilis.
LOCAL_CFLAGS += \
-forder-file-instrumentation \
-mllvm -orderfile-write-mapping=mapping.txt \
LOCAL_LDFLAGS += -forder-file-instrumentation
CMake
Pastikan untuk menggunakan CMAKE_BUILD_TYPE
selain Debug
sehingga CMake menggunakan
mode pengoptimalan selain -O0
. Jika membangun aplikasi dengan AGP, perilaku ini akan otomatis diterapkan
untuk build rilis.
target_compile_options(orderfiledemo PRIVATE
-forder-file-instrumentation
-mllvm -orderfile-write-mapping=mapping.txt
)
target_link_options(orderfiledemo PRIVATE -forder-file-instrumentation)
Sistem build lainnya
Kompilasi kode Anda menggunakan -forder-file-instrumentation -O1 -mllvm
-orderfile-write-mapping=mapping.txt
.
-O1
secara khusus tidak diperlukan, tetapi jangan gunakan -O0
.
Hapus -mllvm -orderfile-write-mapping=mapping.txt
saat menautkan.
Semua tanda ini tidak diperlukan untuk build Rilis sehingga harus dikontrol oleh variabel build. Agar lebih mudah, Anda dapat menyiapkannya di CMakeLists.txt seperti pada contoh.
Membuat Library File Urutan
Selain tanda, file profil harus disiapkan dan biner berinstrumen harus secara eksplisit memicu penulisan profil selama eksekusi.
- Panggil
__llvm_profile_set_filename(PROFILE_DIR "/<filename>-%m.profraw")
untuk menyiapkan jalur profil. Meskipun argumen yang diteruskan adalah<filename>-%m.profraw
, file profil disimpan sebagai<filename>-%m.profraw.order
. PastikanPROFILE_DIR
dapat ditulis oleh aplikasi dan Anda memiliki akses ke direktorinya.- Karena banyaknya pembuatan profil library bersama,
%m
berguna karena diperluas ke tanda tangan modul unik untuk library, sehingga membuat profil terpisah per library. Untuk penentu pola lainnya, Anda dapat melihat referensi lewat link ini.
- Karena banyaknya pembuatan profil library bersama,
- Panggil
__llvm_profile_initialize_file()
untuk menyiapkan file profil - Panggil
__llvm_orderfile_dump()
untuk menulis ke file profil secara eksplisit
Profil dikumpulkan di memori dan fungsi dump akan menulisnya ke file. Anda harus memastikan fungsi dump dipanggil di akhir startup sehingga file profil memiliki semua simbol hingga akhir startup.
extern "C" {
extern int __llvm_profile_set_filename(const char*);
extern int __llvm_profile_initialize_file(void);
extern int __llvm_orderfile_dump(void);
}
#define PROFILE_DIR "<location-writable-from-app>"
void workload() {
// ...
// run workload
// ...
// set path and write profiles after workload execution
__llvm_profile_set_filename(PROFILE_DIR "/default-%m.profraw");
__llvm_profile_initialize_file();
__llvm_orderfile_dump();
return;
}
Menjalankan Build untuk Profil
Jalankan aplikasi berinstrumen pada perangkat fisik atau virtual untuk membuat
profil.
Anda dapat mengekstrak file profil menggunakan adb pull
.
adb shell "run-as <package-name> sh -c 'cat /data/user/0/<package-name>/cache/default-%m.profraw.order' | cat > /data/local/tmp/default-%m.profraw.order"
adb pull /data/local/tmp/default-%m.profraw.order .
Seperti yang disebutkan sebelumnya, pastikan Anda dapat mengakses folder yang berisi file profil tertulis. Jika menggunakan perangkat virtual, sebaiknya hindari emulator dengan Play Store karena tidak memiliki akses ke banyak folder.
Melanjutkan Pemrosesan Profil dan File Pemetaan
Setelah mendapatkan profil, Anda perlu menemukan file pemetaan dan mengonversi setiap profil menjadi format heksadesimal. Biasanya, Anda dapat menemukan file pemetaan dalam folder build aplikasi. Jika memiliki keduanya, Anda dapat menggunakan skrip kami untuk mengambil file profil dan file pemetaan yang benar untuk membuat file urutan.
Linux/Mac/ChromeOS
hexdump -C default-%m.profraw.order > default-%m.prof
python3 create_orderfile.py --profile-file default-%m.prof --mapping-file <filename>-mapping.txt
Windows
certutil -f -encodeHex default-%m.profraw.order default-%m.prof
python3 create_orderfile.py --profile-file default-%m.prof --mapping-file <filename>-mapping.txt
Jika ingin membaca selengkapnya tentang skrip, Anda dapat membaca file README ini.
Menggunakan file Urutan untuk Membangun Aplikasi
Setelah membuat file urutan, Anda harus menghapus tanda sebelumnya dan
fungsi file urutan karena keduanya hanya dimaksudkan untuk langkah-langkah pembuatan.
Anda hanya perlu meneruskan -Wl,--symbol-ordering-file=<filename>.orderfile
ke
tanda compiler dan penaut.
Terkadang, simbol tidak dapat ditemukan atau tidak dapat dipindahkan dan memberikan peringatan, sehingga Anda
dapat meneruskan -Wl,--no-warn-symbol-ordering
untuk menyembunyikan peringatan ini.
ndk-build
LOCAL_CFLAGS += \
-Wl,--symbol-ordering-file=<filename>.orderfile \
-Wl,--no-warn-symbol-ordering \
LOCAL_LDFLAGS += \
-Wl,--symbol-ordering-file=<filename>.orderfile \
-Wl,--no-warn-symbol-ordering \
CMake
target_compile_options(orderfiledemo PRIVATE
-Wl,--symbol-ordering-file=<filename>.orderfile
-Wl,--no-warn-symbol-ordering
)
target_link_options(orderfiledemo PRIVATE
-Wl,--symbol-ordering-file=<filename>.orderfile
-Wl,--no-warn-symbol-ordering
)
Sistem build lainnya
Kompilasi kode Anda menggunakan -Wl,--symbol-ordering-file=<filename>.orderfile
-Wl,--no-warn-symbol-ordering
.
Untuk informasi selengkapnya, lihat contoh file urutan.
Detail implementasi file urutan
Ada banyak cara untuk membuat file urutan dan menggunakannya untuk membangun aplikasi. NDK menggunakan metode LLVM, yang menjadikannya paling berguna untuk library bersama C atau C++ dibandingkan aplikasi Java atau Kotlin aktual. Clang mengambil setiap nama fungsi (simbol) dan membuat hash MD5-nya serta menghasilkan hubungan ini ke file pemetaan. Hash MD5 fungsi ditulis ke dalam file profil (format profraw) saat fungsi dieksekusi untuk pertama kalinya. Setiap eksekusi fungsi berikutnya tidak akan menulis hash MD5-nya ke file profil karena ingin menghindari duplikat. Akibatnya, hanya eksekusi pertama fungsi yang direkam dalam urutan. Dengan memeriksa file profil dan file pemetaan, Anda dapat mengambil setiap hash MD5 dan menggantinya dengan fungsi yang sesuai, lalu mendapatkan file urutan.
Contoh file profil dalam format heksadesimal dan file pemetaan dapat ditemukan sebagai example.prof dan example-mapping.txt.