1*8d67ca89SAndroid Build Coastguard Worker# Bionic Benchmarks 2*8d67ca89SAndroid Build Coastguard Worker 3*8d67ca89SAndroid Build Coastguard Worker[TOC] 4*8d67ca89SAndroid Build Coastguard Worker 5*8d67ca89SAndroid Build Coastguard Worker## libc benchmarks (bionic-benchmarks) 6*8d67ca89SAndroid Build Coastguard Worker 7*8d67ca89SAndroid Build Coastguard Worker`bionic-benchmarks` is a command line tool for measuring the runtimes of libc functions. It is built 8*8d67ca89SAndroid Build Coastguard Workeron top of [Google Benchmark](https://github.com/google/benchmark) with some additions to organize 9*8d67ca89SAndroid Build Coastguard Workertests into suites. 10*8d67ca89SAndroid Build Coastguard Worker 11*8d67ca89SAndroid Build Coastguard Worker### Device benchmarks 12*8d67ca89SAndroid Build Coastguard Worker 13*8d67ca89SAndroid Build Coastguard Worker $ mmma bionic/benchmarks 14*8d67ca89SAndroid Build Coastguard Worker $ adb root 15*8d67ca89SAndroid Build Coastguard Worker $ adb sync data 16*8d67ca89SAndroid Build Coastguard Worker $ adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks 17*8d67ca89SAndroid Build Coastguard Worker $ adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks 18*8d67ca89SAndroid Build Coastguard Worker 19*8d67ca89SAndroid Build Coastguard WorkerBy default, `bionic-benchmarks` runs all of the benchmarks in alphabetical order. Pass 20*8d67ca89SAndroid Build Coastguard Worker`--benchmark_filter=getpid` to run just the benchmarks with "getpid" in their name. 21*8d67ca89SAndroid Build Coastguard Worker 22*8d67ca89SAndroid Build Coastguard WorkerNote that we also build _static_ benchmark binaries. 23*8d67ca89SAndroid Build Coastguard WorkerThey're useful for testing on devices running different versions of Android, or running non-Android OSes. 24*8d67ca89SAndroid Build Coastguard WorkerThose binaries are called `bionic-benchmarks-static` instead. 25*8d67ca89SAndroid Build Coastguard WorkerCopy from `out/target/product/<device>/symbols/data/benchmarktest64/bionic-benchmarks-static` instead of 26*8d67ca89SAndroid Build Coastguard Worker`out/target/product/<device>/data/benchmarktest64/bionic-benchmarks-static` if you want symbols for perf(1). 27*8d67ca89SAndroid Build Coastguard Worker 28*8d67ca89SAndroid Build Coastguard Worker### Host benchmarks 29*8d67ca89SAndroid Build Coastguard Worker 30*8d67ca89SAndroid Build Coastguard WorkerSee the `benchmarks/run-on-host.sh` script. The host benchmarks can be run with 32-bit or 64-bit 31*8d67ca89SAndroid Build Coastguard WorkerBionic, or the host glibc. 32*8d67ca89SAndroid Build Coastguard Worker 33*8d67ca89SAndroid Build Coastguard Worker### XML suites 34*8d67ca89SAndroid Build Coastguard Worker 35*8d67ca89SAndroid Build Coastguard WorkerSuites are stored in the `suites/` directory and can be chosen with the command line flag 36*8d67ca89SAndroid Build Coastguard Worker`--bionic_xml`. 37*8d67ca89SAndroid Build Coastguard Worker 38*8d67ca89SAndroid Build Coastguard WorkerTo choose a specific XML file, use the `--bionic_xml=FILE.XML` option. By default, this option 39*8d67ca89SAndroid Build Coastguard Workersearches for the XML file in the `suites/` directory. If it doesn't exist in that directory, then 40*8d67ca89SAndroid Build Coastguard Workerthe file will be found as relative to the current directory. If the option specifies the full path 41*8d67ca89SAndroid Build Coastguard Workerto an XML file such as `/data/nativetest/suites/example.xml`, it will be used as-is. 42*8d67ca89SAndroid Build Coastguard Worker 43*8d67ca89SAndroid Build Coastguard WorkerIf no XML file is specified through the command-line option, the default is to use `suites/full.xml`. 44*8d67ca89SAndroid Build Coastguard WorkerHowever, for the host bionic benchmarks (`bionic-benchmarks-glibc`), the default is to use 45*8d67ca89SAndroid Build Coastguard Worker`suites/host.xml`. 46*8d67ca89SAndroid Build Coastguard Worker 47*8d67ca89SAndroid Build Coastguard Worker### XML suite format 48*8d67ca89SAndroid Build Coastguard Worker 49*8d67ca89SAndroid Build Coastguard WorkerThe format for a benchmark is: 50*8d67ca89SAndroid Build Coastguard Worker 51*8d67ca89SAndroid Build Coastguard Worker``` 52*8d67ca89SAndroid Build Coastguard Worker<fn> 53*8d67ca89SAndroid Build Coastguard Worker <name>BM_sample_benchmark</name> 54*8d67ca89SAndroid Build Coastguard Worker <cpu><optional_cpu_to_lock></cpu> 55*8d67ca89SAndroid Build Coastguard Worker <iterations><optional_iterations_to_run></iterations> 56*8d67ca89SAndroid Build Coastguard Worker <args><space separated list of function args|shorthand></args> 57*8d67ca89SAndroid Build Coastguard Worker</fn> 58*8d67ca89SAndroid Build Coastguard Worker``` 59*8d67ca89SAndroid Build Coastguard Worker 60*8d67ca89SAndroid Build Coastguard WorkerXML-specified values for iterations and cpu take precedence over those specified via command line 61*8d67ca89SAndroid Build Coastguard Worker(via `--bionic_iterations` and `--bionic_cpu`, respectively.) 62*8d67ca89SAndroid Build Coastguard Worker 63*8d67ca89SAndroid Build Coastguard WorkerTo make small changes in runs, you can also schedule benchmarks by passing in their name and a 64*8d67ca89SAndroid Build Coastguard Workerspace-separated list of arguments via the `--bionic_extra` command line flag, e.g. 65*8d67ca89SAndroid Build Coastguard Worker`--bionic_extra="BM_string_memcpy AT_COMMON_SIZES"` or `--bionic_extra="BM_string_memcmp 32 8 8"` 66*8d67ca89SAndroid Build Coastguard Worker 67*8d67ca89SAndroid Build Coastguard WorkerNote that benchmarks will run normally if extra arguments are passed in, and it will fail 68*8d67ca89SAndroid Build Coastguard Workerwith a segfault if too few are passed in. 69*8d67ca89SAndroid Build Coastguard Worker 70*8d67ca89SAndroid Build Coastguard Worker### Shorthand 71*8d67ca89SAndroid Build Coastguard Worker 72*8d67ca89SAndroid Build Coastguard WorkerFor the sake of brevity, multiple runs can be scheduled in one XML element by putting one of the 73*8d67ca89SAndroid Build Coastguard Workerfollowing in the args field: 74*8d67ca89SAndroid Build Coastguard Worker 75*8d67ca89SAndroid Build Coastguard Worker NUM_PROPS 76*8d67ca89SAndroid Build Coastguard Worker MATH_COMMON 77*8d67ca89SAndroid Build Coastguard Worker AT_ALIGNED_<ONE|TWO>BUF 78*8d67ca89SAndroid Build Coastguard Worker AT_<any power of two between 2 and 16384>_ALIGNED_<ONE|TWO>BUF 79*8d67ca89SAndroid Build Coastguard Worker AT_COMMON_SIZES 80*8d67ca89SAndroid Build Coastguard Worker 81*8d67ca89SAndroid Build Coastguard WorkerDefinitions for these can be found in bionic_benchmarks.cpp, and example usages can be found in 82*8d67ca89SAndroid Build Coastguard Workerthe suites directory. 83*8d67ca89SAndroid Build Coastguard Worker 84*8d67ca89SAndroid Build Coastguard Worker### Unit Tests 85*8d67ca89SAndroid Build Coastguard Worker 86*8d67ca89SAndroid Build Coastguard Worker`bionic-benchmarks` also has its own set of unit tests, which can be run from the binary in 87*8d67ca89SAndroid Build Coastguard Worker`/data/nativetest[64]/bionic-benchmarks-tests` 88*8d67ca89SAndroid Build Coastguard Worker 89*8d67ca89SAndroid Build Coastguard Worker## Process startup time (bionic-spawn-benchmarks) 90*8d67ca89SAndroid Build Coastguard Worker 91*8d67ca89SAndroid Build Coastguard WorkerThe `spawn/` subdirectory has a few benchmarks measuring the time used to start simple programs 92*8d67ca89SAndroid Build Coastguard Worker(e.g. Toybox's `true` and `sh -c true`). Run it on a device like so: 93*8d67ca89SAndroid Build Coastguard Worker 94*8d67ca89SAndroid Build Coastguard Worker m bionic-spawn-benchmarks 95*8d67ca89SAndroid Build Coastguard Worker adb root 96*8d67ca89SAndroid Build Coastguard Worker adb sync data 97*8d67ca89SAndroid Build Coastguard Worker adb shell /data/benchmarktest/bionic-spawn-benchmarks/bionic-spawn-benchmarks 98*8d67ca89SAndroid Build Coastguard Worker adb shell /data/benchmarktest64/bionic-spawn-benchmarks/bionic-spawn-benchmarks 99*8d67ca89SAndroid Build Coastguard Worker 100*8d67ca89SAndroid Build Coastguard WorkerGoogle Benchmark reports both a real-time figure ("Time") and a CPU usage figure. For these 101*8d67ca89SAndroid Build Coastguard Workerbenchmarks, the CPU measurement only counts time spent in the thread calling `posix_spawn`, not that 102*8d67ca89SAndroid Build Coastguard Workerspent in the spawned process. The real-time is probably more useful, and it is the figure used to 103*8d67ca89SAndroid Build Coastguard Workerdetermine the iteration count. 104*8d67ca89SAndroid Build Coastguard Worker 105*8d67ca89SAndroid Build Coastguard WorkerLocking the CPU frequency seems to improve the results of these benchmarks significantly, and it 106*8d67ca89SAndroid Build Coastguard Workerreduces variability. 107*8d67ca89SAndroid Build Coastguard Worker 108*8d67ca89SAndroid Build Coastguard Worker## Google Benchmark notes 109*8d67ca89SAndroid Build Coastguard Worker 110*8d67ca89SAndroid Build Coastguard Worker### Repetitions 111*8d67ca89SAndroid Build Coastguard Worker 112*8d67ca89SAndroid Build Coastguard WorkerGoogle Benchmark uses two settings to control how many times to run each benchmark, "iterations" and 113*8d67ca89SAndroid Build Coastguard Worker"repetitions". By default, the repetition count is one. Google Benchmark runs the benchmark a few 114*8d67ca89SAndroid Build Coastguard Workertimes to determine a sufficiently-large iteration count. 115*8d67ca89SAndroid Build Coastguard Worker 116*8d67ca89SAndroid Build Coastguard WorkerGoogle Benchmark can optionally run a benchmark run repeatedly and report statistics (median, mean, 117*8d67ca89SAndroid Build Coastguard Workerstandard deviation) for the runs. To do so, pass the `--benchmark_repetitions` option, e.g.: 118*8d67ca89SAndroid Build Coastguard Worker 119*8d67ca89SAndroid Build Coastguard Worker # ./bionic-benchmarks --benchmark_filter=BM_stdlib_strtoll --benchmark_repetitions=4 120*8d67ca89SAndroid Build Coastguard Worker ... 121*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------------- 122*8d67ca89SAndroid Build Coastguard Worker Benchmark Time CPU Iterations 123*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------------- 124*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll 27.7 ns 27.7 ns 25290525 125*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll 27.7 ns 27.7 ns 25290525 126*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll 27.7 ns 27.7 ns 25290525 127*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll 27.8 ns 27.7 ns 25290525 128*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll_mean 27.7 ns 27.7 ns 4 129*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll_median 27.7 ns 27.7 ns 4 130*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll_stddev 0.023 ns 0.023 ns 4 131*8d67ca89SAndroid Build Coastguard Worker 132*8d67ca89SAndroid Build Coastguard WorkerThere are 4 runs, each with 25290525 iterations. Measurements for the individual runs can be 133*8d67ca89SAndroid Build Coastguard Workersuppressed if they aren't needed: 134*8d67ca89SAndroid Build Coastguard Worker 135*8d67ca89SAndroid Build Coastguard Worker # ./bionic-benchmarks --benchmark_filter=BM_stdlib_strtoll --benchmark_repetitions=4 --benchmark_report_aggregates_only 136*8d67ca89SAndroid Build Coastguard Worker ... 137*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------------- 138*8d67ca89SAndroid Build Coastguard Worker Benchmark Time CPU Iterations 139*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------------- 140*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll_mean 27.8 ns 27.7 ns 4 141*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll_median 27.7 ns 27.7 ns 4 142*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll_stddev 0.043 ns 0.043 ns 4 143*8d67ca89SAndroid Build Coastguard Worker 144*8d67ca89SAndroid Build Coastguard Worker### CPU frequencies 145*8d67ca89SAndroid Build Coastguard Worker 146*8d67ca89SAndroid Build Coastguard WorkerTo get consistent results between runs, it can sometimes be helpful to restrict a benchmark to 147*8d67ca89SAndroid Build Coastguard Workerspecific cores, or to lock cores at specific frequencies. Some phones have a big.LITTLE core setup, 148*8d67ca89SAndroid Build Coastguard Workeror at least allow some cores to run at higher frequencies than others. 149*8d67ca89SAndroid Build Coastguard Worker 150*8d67ca89SAndroid Build Coastguard WorkerA core can be selected for `bionic-benchmarks` using the `--bionic_cpu` option or using the 151*8d67ca89SAndroid Build Coastguard Worker`taskset` utility. e.g. A Pixel 3 device has 4 Kryo 385 Silver cores followed by 4 Gold cores: 152*8d67ca89SAndroid Build Coastguard Worker 153*8d67ca89SAndroid Build Coastguard Worker blueline:/ # /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=BM_stdlib_strtoll --bionic_cpu=0 154*8d67ca89SAndroid Build Coastguard Worker ... 155*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------ 156*8d67ca89SAndroid Build Coastguard Worker Benchmark Time CPU Iterations 157*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------ 158*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll 64.2 ns 63.6 ns 11017493 159*8d67ca89SAndroid Build Coastguard Worker 160*8d67ca89SAndroid Build Coastguard Worker blueline:/ # /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=BM_stdlib_strtoll --bionic_cpu=4 161*8d67ca89SAndroid Build Coastguard Worker ... 162*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------ 163*8d67ca89SAndroid Build Coastguard Worker Benchmark Time CPU Iterations 164*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------ 165*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll 21.8 ns 21.7 ns 33167103 166*8d67ca89SAndroid Build Coastguard Worker 167*8d67ca89SAndroid Build Coastguard WorkerA similar result can be achieved using `taskset`. The first parameter is a bitmask of core numbers 168*8d67ca89SAndroid Build Coastguard Workerto pass to `sched_setaffinity`: 169*8d67ca89SAndroid Build Coastguard Worker 170*8d67ca89SAndroid Build Coastguard Worker blueline:/ # taskset f /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=BM_stdlib_strtoll 171*8d67ca89SAndroid Build Coastguard Worker ... 172*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------ 173*8d67ca89SAndroid Build Coastguard Worker Benchmark Time CPU Iterations 174*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------ 175*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll 64.3 ns 63.6 ns 10998697 176*8d67ca89SAndroid Build Coastguard Worker 177*8d67ca89SAndroid Build Coastguard Worker blueline:/ # taskset f0 /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=BM_stdlib_strtoll 178*8d67ca89SAndroid Build Coastguard Worker ... 179*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------ 180*8d67ca89SAndroid Build Coastguard Worker Benchmark Time CPU Iterations 181*8d67ca89SAndroid Build Coastguard Worker ------------------------------------------------------------ 182*8d67ca89SAndroid Build Coastguard Worker BM_stdlib_strtoll 21.3 ns 21.2 ns 33094801 183*8d67ca89SAndroid Build Coastguard Worker 184*8d67ca89SAndroid Build Coastguard WorkerTo lock the CPU frequency, use the sysfs interface at `/sys/devices/system/cpu/cpu*/cpufreq/`. 185*8d67ca89SAndroid Build Coastguard WorkerChanging the scaling governor to `performance` suppresses the warning that Google Benchmark 186*8d67ca89SAndroid Build Coastguard Workerotherwise prints: 187*8d67ca89SAndroid Build Coastguard Worker 188*8d67ca89SAndroid Build Coastguard Worker ***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead. 189*8d67ca89SAndroid Build Coastguard Worker 190*8d67ca89SAndroid Build Coastguard WorkerSome devices have a `perf-setup.sh` script that locks CPU and GPU frequencies. Some TradeFed 191*8d67ca89SAndroid Build Coastguard Workerbenchmarks appear to be using the script. For more information: 192*8d67ca89SAndroid Build Coastguard Worker * run `adb shell perf-setup.sh` to execute the script, it is already by default be installed on device for eng and userdebug build 193*8d67ca89SAndroid Build Coastguard Worker * see: https://android.googlesource.com/platform/platform_testing/+/refs/heads/main/scripts/perf-setup/ 194