xref: /aosp_15_r20/external/libcxx/utils/google-benchmark/docs/tools.md (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
1*58b9f456SAndroid Build Coastguard Worker# Benchmark Tools
2*58b9f456SAndroid Build Coastguard Worker
3*58b9f456SAndroid Build Coastguard Worker## compare.py
4*58b9f456SAndroid Build Coastguard Worker
5*58b9f456SAndroid Build Coastguard WorkerThe `compare.py` can be used to compare the result of benchmarks.
6*58b9f456SAndroid Build Coastguard Worker
7*58b9f456SAndroid Build Coastguard Worker**NOTE**: the utility relies on the scipy package which can be installed using [these instructions](https://www.scipy.org/install.html).
8*58b9f456SAndroid Build Coastguard Worker
9*58b9f456SAndroid Build Coastguard Worker### Displaying aggregates only
10*58b9f456SAndroid Build Coastguard Worker
11*58b9f456SAndroid Build Coastguard WorkerThe switch `-a` / `--display_aggregates_only` can be used to control the
12*58b9f456SAndroid Build Coastguard Workerdisplayment of the normal iterations vs the aggregates. When passed, it will
13*58b9f456SAndroid Build Coastguard Workerbe passthrough to the benchmark binaries to be run, and will be accounted for
14*58b9f456SAndroid Build Coastguard Workerin the tool itself; only the aggregates will be displayed, but not normal runs.
15*58b9f456SAndroid Build Coastguard WorkerIt only affects the display, the separate runs will still be used to calculate
16*58b9f456SAndroid Build Coastguard Workerthe U test.
17*58b9f456SAndroid Build Coastguard Worker
18*58b9f456SAndroid Build Coastguard Worker### Modes of operation
19*58b9f456SAndroid Build Coastguard Worker
20*58b9f456SAndroid Build Coastguard WorkerThere are three modes of operation:
21*58b9f456SAndroid Build Coastguard Worker
22*58b9f456SAndroid Build Coastguard Worker1. Just compare two benchmarks
23*58b9f456SAndroid Build Coastguard WorkerThe program is invoked like:
24*58b9f456SAndroid Build Coastguard Worker
25*58b9f456SAndroid Build Coastguard Worker``` bash
26*58b9f456SAndroid Build Coastguard Worker$ compare.py benchmarks <benchmark_baseline> <benchmark_contender> [benchmark options]...
27*58b9f456SAndroid Build Coastguard Worker```
28*58b9f456SAndroid Build Coastguard WorkerWhere `<benchmark_baseline>` and `<benchmark_contender>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
29*58b9f456SAndroid Build Coastguard Worker
30*58b9f456SAndroid Build Coastguard Worker`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
31*58b9f456SAndroid Build Coastguard Worker
32*58b9f456SAndroid Build Coastguard WorkerExample output:
33*58b9f456SAndroid Build Coastguard Worker```
34*58b9f456SAndroid Build Coastguard Worker$ ./compare.py benchmarks ./a.out ./a.out
35*58b9f456SAndroid Build Coastguard WorkerRUNNING: ./a.out --benchmark_out=/tmp/tmprBT5nW
36*58b9f456SAndroid Build Coastguard WorkerRun on (8 X 4000 MHz CPU s)
37*58b9f456SAndroid Build Coastguard Worker2017-11-07 21:16:44
38*58b9f456SAndroid Build Coastguard Worker------------------------------------------------------
39*58b9f456SAndroid Build Coastguard WorkerBenchmark               Time           CPU Iterations
40*58b9f456SAndroid Build Coastguard Worker------------------------------------------------------
41*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/8            36 ns         36 ns   19101577   211.669MB/s
42*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/64           76 ns         76 ns    9412571   800.199MB/s
43*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/512          84 ns         84 ns    8249070   5.64771GB/s
44*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/1024        116 ns        116 ns    6181763   8.19505GB/s
45*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/8192        643 ns        643 ns    1062855   11.8636GB/s
46*58b9f456SAndroid Build Coastguard WorkerBM_copy/8             222 ns        222 ns    3137987   34.3772MB/s
47*58b9f456SAndroid Build Coastguard WorkerBM_copy/64           1608 ns       1608 ns     432758   37.9501MB/s
48*58b9f456SAndroid Build Coastguard WorkerBM_copy/512         12589 ns      12589 ns      54806   38.7867MB/s
49*58b9f456SAndroid Build Coastguard WorkerBM_copy/1024        25169 ns      25169 ns      27713   38.8003MB/s
50*58b9f456SAndroid Build Coastguard WorkerBM_copy/8192       201165 ns     201112 ns       3486   38.8466MB/s
51*58b9f456SAndroid Build Coastguard WorkerRUNNING: ./a.out --benchmark_out=/tmp/tmpt1wwG_
52*58b9f456SAndroid Build Coastguard WorkerRun on (8 X 4000 MHz CPU s)
53*58b9f456SAndroid Build Coastguard Worker2017-11-07 21:16:53
54*58b9f456SAndroid Build Coastguard Worker------------------------------------------------------
55*58b9f456SAndroid Build Coastguard WorkerBenchmark               Time           CPU Iterations
56*58b9f456SAndroid Build Coastguard Worker------------------------------------------------------
57*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/8            36 ns         36 ns   19397903   211.255MB/s
58*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/64           73 ns         73 ns    9691174   839.635MB/s
59*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/512          85 ns         85 ns    8312329   5.60101GB/s
60*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/1024        118 ns        118 ns    6438774   8.11608GB/s
61*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/8192        656 ns        656 ns    1068644   11.6277GB/s
62*58b9f456SAndroid Build Coastguard WorkerBM_copy/8             223 ns        223 ns    3146977   34.2338MB/s
63*58b9f456SAndroid Build Coastguard WorkerBM_copy/64           1611 ns       1611 ns     435340   37.8751MB/s
64*58b9f456SAndroid Build Coastguard WorkerBM_copy/512         12622 ns      12622 ns      54818   38.6844MB/s
65*58b9f456SAndroid Build Coastguard WorkerBM_copy/1024        25257 ns      25239 ns      27779   38.6927MB/s
66*58b9f456SAndroid Build Coastguard WorkerBM_copy/8192       205013 ns     205010 ns       3479    38.108MB/s
67*58b9f456SAndroid Build Coastguard WorkerComparing ./a.out to ./a.out
68*58b9f456SAndroid Build Coastguard WorkerBenchmark                 Time             CPU      Time Old      Time New       CPU Old       CPU New
69*58b9f456SAndroid Build Coastguard Worker------------------------------------------------------------------------------------------------------
70*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/8            +0.0020         +0.0020            36            36            36            36
71*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/64           -0.0468         -0.0470            76            73            76            73
72*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/512          +0.0081         +0.0083            84            85            84            85
73*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/1024         +0.0098         +0.0097           116           118           116           118
74*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/8192         +0.0200         +0.0203           643           656           643           656
75*58b9f456SAndroid Build Coastguard WorkerBM_copy/8              +0.0046         +0.0042           222           223           222           223
76*58b9f456SAndroid Build Coastguard WorkerBM_copy/64             +0.0020         +0.0020          1608          1611          1608          1611
77*58b9f456SAndroid Build Coastguard WorkerBM_copy/512            +0.0027         +0.0026         12589         12622         12589         12622
78*58b9f456SAndroid Build Coastguard WorkerBM_copy/1024           +0.0035         +0.0028         25169         25257         25169         25239
79*58b9f456SAndroid Build Coastguard WorkerBM_copy/8192           +0.0191         +0.0194        201165        205013        201112        205010
80*58b9f456SAndroid Build Coastguard Worker```
81*58b9f456SAndroid Build Coastguard Worker
82*58b9f456SAndroid Build Coastguard WorkerWhat it does is for the every benchmark from the first run it looks for the benchmark with exactly the same name in the second run, and then compares the results. If the names differ, the benchmark is omitted from the diff.
83*58b9f456SAndroid Build Coastguard WorkerAs you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
84*58b9f456SAndroid Build Coastguard Worker
85*58b9f456SAndroid Build Coastguard Worker2. Compare two different filters of one benchmark
86*58b9f456SAndroid Build Coastguard WorkerThe program is invoked like:
87*58b9f456SAndroid Build Coastguard Worker
88*58b9f456SAndroid Build Coastguard Worker``` bash
89*58b9f456SAndroid Build Coastguard Worker$ compare.py filters <benchmark> <filter_baseline> <filter_contender> [benchmark options]...
90*58b9f456SAndroid Build Coastguard Worker```
91*58b9f456SAndroid Build Coastguard WorkerWhere `<benchmark>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
92*58b9f456SAndroid Build Coastguard Worker
93*58b9f456SAndroid Build Coastguard WorkerWhere `<filter_baseline>` and `<filter_contender>` are the same regex filters that you would pass to the `[--benchmark_filter=<regex>]` parameter of the benchmark binary.
94*58b9f456SAndroid Build Coastguard Worker
95*58b9f456SAndroid Build Coastguard Worker`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
96*58b9f456SAndroid Build Coastguard Worker
97*58b9f456SAndroid Build Coastguard WorkerExample output:
98*58b9f456SAndroid Build Coastguard Worker```
99*58b9f456SAndroid Build Coastguard Worker$ ./compare.py filters ./a.out BM_memcpy BM_copy
100*58b9f456SAndroid Build Coastguard WorkerRUNNING: ./a.out --benchmark_filter=BM_memcpy --benchmark_out=/tmp/tmpBWKk0k
101*58b9f456SAndroid Build Coastguard WorkerRun on (8 X 4000 MHz CPU s)
102*58b9f456SAndroid Build Coastguard Worker2017-11-07 21:37:28
103*58b9f456SAndroid Build Coastguard Worker------------------------------------------------------
104*58b9f456SAndroid Build Coastguard WorkerBenchmark               Time           CPU Iterations
105*58b9f456SAndroid Build Coastguard Worker------------------------------------------------------
106*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/8            36 ns         36 ns   17891491   211.215MB/s
107*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/64           74 ns         74 ns    9400999   825.646MB/s
108*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/512          87 ns         87 ns    8027453   5.46126GB/s
109*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/1024        111 ns        111 ns    6116853    8.5648GB/s
110*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/8192        657 ns        656 ns    1064679   11.6247GB/s
111*58b9f456SAndroid Build Coastguard WorkerRUNNING: ./a.out --benchmark_filter=BM_copy --benchmark_out=/tmp/tmpAvWcOM
112*58b9f456SAndroid Build Coastguard WorkerRun on (8 X 4000 MHz CPU s)
113*58b9f456SAndroid Build Coastguard Worker2017-11-07 21:37:33
114*58b9f456SAndroid Build Coastguard Worker----------------------------------------------------
115*58b9f456SAndroid Build Coastguard WorkerBenchmark             Time           CPU Iterations
116*58b9f456SAndroid Build Coastguard Worker----------------------------------------------------
117*58b9f456SAndroid Build Coastguard WorkerBM_copy/8           227 ns        227 ns    3038700   33.6264MB/s
118*58b9f456SAndroid Build Coastguard WorkerBM_copy/64         1640 ns       1640 ns     426893   37.2154MB/s
119*58b9f456SAndroid Build Coastguard WorkerBM_copy/512       12804 ns      12801 ns      55417   38.1444MB/s
120*58b9f456SAndroid Build Coastguard WorkerBM_copy/1024      25409 ns      25407 ns      27516   38.4365MB/s
121*58b9f456SAndroid Build Coastguard WorkerBM_copy/8192     202986 ns     202990 ns       3454   38.4871MB/s
122*58b9f456SAndroid Build Coastguard WorkerComparing BM_memcpy to BM_copy (from ./a.out)
123*58b9f456SAndroid Build Coastguard WorkerBenchmark                               Time             CPU      Time Old      Time New       CPU Old       CPU New
124*58b9f456SAndroid Build Coastguard Worker--------------------------------------------------------------------------------------------------------------------
125*58b9f456SAndroid Build Coastguard Worker[BM_memcpy vs. BM_copy]/8            +5.2829         +5.2812            36           227            36           227
126*58b9f456SAndroid Build Coastguard Worker[BM_memcpy vs. BM_copy]/64          +21.1719        +21.1856            74          1640            74          1640
127*58b9f456SAndroid Build Coastguard Worker[BM_memcpy vs. BM_copy]/512        +145.6487       +145.6097            87         12804            87         12801
128*58b9f456SAndroid Build Coastguard Worker[BM_memcpy vs. BM_copy]/1024       +227.1860       +227.1776           111         25409           111         25407
129*58b9f456SAndroid Build Coastguard Worker[BM_memcpy vs. BM_copy]/8192       +308.1664       +308.2898           657        202986           656        202990
130*58b9f456SAndroid Build Coastguard Worker```
131*58b9f456SAndroid Build Coastguard Worker
132*58b9f456SAndroid Build Coastguard WorkerAs you can see, it applies filter to the benchmarks, both when running the benchmark, and before doing the diff. And to make the diff work, the matches are replaced with some common string. Thus, you can compare two different benchmark families within one benchmark binary.
133*58b9f456SAndroid Build Coastguard WorkerAs you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
134*58b9f456SAndroid Build Coastguard Worker
135*58b9f456SAndroid Build Coastguard Worker3. Compare filter one from benchmark one to filter two from benchmark two:
136*58b9f456SAndroid Build Coastguard WorkerThe program is invoked like:
137*58b9f456SAndroid Build Coastguard Worker
138*58b9f456SAndroid Build Coastguard Worker``` bash
139*58b9f456SAndroid Build Coastguard Worker$ compare.py filters <benchmark_baseline> <filter_baseline> <benchmark_contender> <filter_contender> [benchmark options]...
140*58b9f456SAndroid Build Coastguard Worker```
141*58b9f456SAndroid Build Coastguard Worker
142*58b9f456SAndroid Build Coastguard WorkerWhere `<benchmark_baseline>` and `<benchmark_contender>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
143*58b9f456SAndroid Build Coastguard Worker
144*58b9f456SAndroid Build Coastguard WorkerWhere `<filter_baseline>` and `<filter_contender>` are the same regex filters that you would pass to the `[--benchmark_filter=<regex>]` parameter of the benchmark binary.
145*58b9f456SAndroid Build Coastguard Worker
146*58b9f456SAndroid Build Coastguard Worker`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
147*58b9f456SAndroid Build Coastguard Worker
148*58b9f456SAndroid Build Coastguard WorkerExample output:
149*58b9f456SAndroid Build Coastguard Worker```
150*58b9f456SAndroid Build Coastguard Worker$ ./compare.py benchmarksfiltered ./a.out BM_memcpy ./a.out BM_copy
151*58b9f456SAndroid Build Coastguard WorkerRUNNING: ./a.out --benchmark_filter=BM_memcpy --benchmark_out=/tmp/tmp_FvbYg
152*58b9f456SAndroid Build Coastguard WorkerRun on (8 X 4000 MHz CPU s)
153*58b9f456SAndroid Build Coastguard Worker2017-11-07 21:38:27
154*58b9f456SAndroid Build Coastguard Worker------------------------------------------------------
155*58b9f456SAndroid Build Coastguard WorkerBenchmark               Time           CPU Iterations
156*58b9f456SAndroid Build Coastguard Worker------------------------------------------------------
157*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/8            37 ns         37 ns   18953482   204.118MB/s
158*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/64           74 ns         74 ns    9206578   828.245MB/s
159*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/512          91 ns         91 ns    8086195   5.25476GB/s
160*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/1024        120 ns        120 ns    5804513   7.95662GB/s
161*58b9f456SAndroid Build Coastguard WorkerBM_memcpy/8192        664 ns        664 ns    1028363   11.4948GB/s
162*58b9f456SAndroid Build Coastguard WorkerRUNNING: ./a.out --benchmark_filter=BM_copy --benchmark_out=/tmp/tmpDfL5iE
163*58b9f456SAndroid Build Coastguard WorkerRun on (8 X 4000 MHz CPU s)
164*58b9f456SAndroid Build Coastguard Worker2017-11-07 21:38:32
165*58b9f456SAndroid Build Coastguard Worker----------------------------------------------------
166*58b9f456SAndroid Build Coastguard WorkerBenchmark             Time           CPU Iterations
167*58b9f456SAndroid Build Coastguard Worker----------------------------------------------------
168*58b9f456SAndroid Build Coastguard WorkerBM_copy/8           230 ns        230 ns    2985909   33.1161MB/s
169*58b9f456SAndroid Build Coastguard WorkerBM_copy/64         1654 ns       1653 ns     419408   36.9137MB/s
170*58b9f456SAndroid Build Coastguard WorkerBM_copy/512       13122 ns      13120 ns      53403   37.2156MB/s
171*58b9f456SAndroid Build Coastguard WorkerBM_copy/1024      26679 ns      26666 ns      26575   36.6218MB/s
172*58b9f456SAndroid Build Coastguard WorkerBM_copy/8192     215068 ns     215053 ns       3221   36.3283MB/s
173*58b9f456SAndroid Build Coastguard WorkerComparing BM_memcpy (from ./a.out) to BM_copy (from ./a.out)
174*58b9f456SAndroid Build Coastguard WorkerBenchmark                               Time             CPU      Time Old      Time New       CPU Old       CPU New
175*58b9f456SAndroid Build Coastguard Worker--------------------------------------------------------------------------------------------------------------------
176*58b9f456SAndroid Build Coastguard Worker[BM_memcpy vs. BM_copy]/8            +5.1649         +5.1637            37           230            37           230
177*58b9f456SAndroid Build Coastguard Worker[BM_memcpy vs. BM_copy]/64          +21.4352        +21.4374            74          1654            74          1653
178*58b9f456SAndroid Build Coastguard Worker[BM_memcpy vs. BM_copy]/512        +143.6022       +143.5865            91         13122            91         13120
179*58b9f456SAndroid Build Coastguard Worker[BM_memcpy vs. BM_copy]/1024       +221.5903       +221.4790           120         26679           120         26666
180*58b9f456SAndroid Build Coastguard Worker[BM_memcpy vs. BM_copy]/8192       +322.9059       +323.0096           664        215068           664        215053
181*58b9f456SAndroid Build Coastguard Worker```
182*58b9f456SAndroid Build Coastguard WorkerThis is a mix of the previous two modes, two (potentially different) benchmark binaries are run, and a different filter is applied to each one.
183*58b9f456SAndroid Build Coastguard WorkerAs you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
184*58b9f456SAndroid Build Coastguard Worker
185*58b9f456SAndroid Build Coastguard Worker### U test
186*58b9f456SAndroid Build Coastguard Worker
187*58b9f456SAndroid Build Coastguard WorkerIf there is a sufficient repetition count of the benchmarks, the tool can do
188*58b9f456SAndroid Build Coastguard Workera [U Test](https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test), of the
189*58b9f456SAndroid Build Coastguard Workernull hypothesis that it is equally likely that a randomly selected value from
190*58b9f456SAndroid Build Coastguard Workerone sample will be less than or greater than a randomly selected value from a
191*58b9f456SAndroid Build Coastguard Workersecond sample.
192*58b9f456SAndroid Build Coastguard Worker
193*58b9f456SAndroid Build Coastguard WorkerIf the calculated p-value is below this value is lower than the significance
194*58b9f456SAndroid Build Coastguard Workerlevel alpha, then the result is said to be statistically significant and the
195*58b9f456SAndroid Build Coastguard Workernull hypothesis is rejected. Which in other words means that the two benchmarks
196*58b9f456SAndroid Build Coastguard Workeraren't identical.
197*58b9f456SAndroid Build Coastguard Worker
198*58b9f456SAndroid Build Coastguard Worker**WARNING**: requires **LARGE** (no less than 9) number of repetitions to be
199*58b9f456SAndroid Build Coastguard Workermeaningful!
200