diff --git a/gki/aarch64/afdo/README.md b/gki/aarch64/afdo/README.md new file mode 100644 index 000000000000..f162e4203d45 --- /dev/null +++ b/gki/aarch64/afdo/README.md @@ -0,0 +1,81 @@ +# AutoFDO profiles for Android common kernels + +This directory contains AutoFDO profiles for Android common kernels. These profiles are used to +optimize kernel builds, improving performance for specific architectures and kernel versions. + +## Profile Availability + +The AutoFDO profile (kernel.afdo) for vmlinux is updated regularly for the following kernel +branches: + +* [android15-6.6](https://android.googlesource.com/kernel/common/+/refs/heads/android15-6.6/android/gki/aarch64/afdo) +* [android16-6.12](https://android.googlesource.com/kernel/common/+/refs/heads/android16-6.12/gki/aarch64/afdo/) + + +## Performance improvements + +When applying these AutoFDO profiles to the android15-6.6 and android16-6.12 kernels, we observed +the following performance improvements during testing on a Pixel 6 device. + + +| Benchmark | Improvement | +| --------------------- | ----------- | +| Boot time | 2-3% | +| Cold App launch time | 3-4% | +| Binder-rpc | 8-9% | +| Binder-addints | 12-25% | +| Hwbinder | 12-18% | +| Bionic (syscall_mmap) | 6% | + + +## Steps to reproduce the profile + +A kernel profile is generated by running app crawling and app launching for top 100 apps from Google +Play Store. While running, we collect ETM data for the kernel, which records executed instruction +stream. Finally, we merge and convert ETM data to one AutoFDO profile. + +### 1. Build a kernel image and flash it on an Android device + * The source code and test device used to generate each profile are described above. + * We use a Pixel device. But using other real devices should get a similar profile. + +### 2. Run app crawling and app launching for top 100 apps + * Add a gmail account on the test device. Because app crawler can use the account to automatically + login some of the apps. + * We run [App Crawler](https://developer.android.com/studio/test/other-testing-tools/app-crawler) + for one app for 3 minutes, and run it twice. + * We run app launching for one app for 3 seconds, and run it 15 times. After each running, the + app is killed and cache is cleared. So we get profile for cold app startups. + +### 3. Generate the AutoFDO profile + +First, collect performance data using simpleperf with Coresight ETM or ARM ETE while running app +crawling and app launching scenarios. Following is an example recording kernel activity for 180 +seconds. For a complete guide, refer to [Record ETM data for the kernel](https://android.googlesource.com/platform/system/extras/+/refs/heads/android16-release/simpleperf/doc/collect_etm_data_for_autofdo.md#A-complete-example_kernel). + +```sh +(device) / $ simpleperf record -e cs-etm:k -a --duration 180 -z -o perf.data +``` + +Next, convert the ETM data to an AutoFDO profile using `simpleperf inject` and `create_llvm_prof` +on the host machine. For a complete guide, refer to [Convert ETM data to AutoFDO Profile on Host](https://android.googlesource.com/platform/system/extras/+/refs/heads/android16-release/simpleperf/doc/collect_etm_data_for_autofdo.md#A-complete-example_kernel). + +Note that `create_llvm_prof` recently enabled the symbol list by default, which can cause Clang +to de-optimize any kernel function not listed in the profile. This is usually not we want in the +kernel, unless the profile cover all critical paths. So we recommend adding `--prof_sym_list=false` +to avoid de-optimization. This also prevents the following build error from section mismatch. + +``` +WARNING: modpost: vmlinux: section mismatch in reference: list_add+0x0 (section: .text.hot.list_add) -> dir_list (section: .init.data) +``` + +We use the following command to perform the conversion. + +```sh +# Convert the AutoFDO profile to the LLVM profile format: +# The --prof_sym_list=false flag is important for kernel profiles. Without it, clang +# assumes any function not listed in the profile is cold. This can lead to unwanted +# deoptimizations, even when -fprofile-sample-accurate is not enabled. +(host) $ create_llvm_prof --profiler=text --binary={vmlinux_dir}/vmlinux \ + --profile=kernel.autofdo --format=extbinary --use_fs_discriminator \ + --out=kernel.afdo --prof_sym_list=false +```