xref: /aosp_15_r20/external/google-benchmark/docs/reducing_variance.md (revision dbb99499c3810fa1611fa2242a2fc446be01a57c)
1*dbb99499SAndroid Build Coastguard Worker# Reducing Variance
2*dbb99499SAndroid Build Coastguard Worker
3*dbb99499SAndroid Build Coastguard Worker<a name="disabling-cpu-frequency-scaling" />
4*dbb99499SAndroid Build Coastguard Worker
5*dbb99499SAndroid Build Coastguard Worker## Disabling CPU Frequency Scaling
6*dbb99499SAndroid Build Coastguard Worker
7*dbb99499SAndroid Build Coastguard WorkerIf you see this error:
8*dbb99499SAndroid Build Coastguard Worker
9*dbb99499SAndroid Build Coastguard Worker```
10*dbb99499SAndroid Build Coastguard Worker***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead.
11*dbb99499SAndroid Build Coastguard Worker```
12*dbb99499SAndroid Build Coastguard Worker
13*dbb99499SAndroid Build Coastguard Workeryou might want to disable the CPU frequency scaling while running the
14*dbb99499SAndroid Build Coastguard Workerbenchmark, as well as consider other ways to stabilize the performance of
15*dbb99499SAndroid Build Coastguard Workeryour system while benchmarking.
16*dbb99499SAndroid Build Coastguard Worker
17*dbb99499SAndroid Build Coastguard WorkerExactly how to do this depends on the Linux distribution,
18*dbb99499SAndroid Build Coastguard Workerdesktop environment, and installed programs.  Specific details are a moving
19*dbb99499SAndroid Build Coastguard Workertarget, so we will not attempt to exhaustively document them here.
20*dbb99499SAndroid Build Coastguard Worker
21*dbb99499SAndroid Build Coastguard WorkerOne simple option is to use the `cpupower` program to change the
22*dbb99499SAndroid Build Coastguard Workerperformance governor to "performance".  This tool is maintained along with
23*dbb99499SAndroid Build Coastguard Workerthe Linux kernel and provided by your distribution.
24*dbb99499SAndroid Build Coastguard Worker
25*dbb99499SAndroid Build Coastguard WorkerIt must be run as root, like this:
26*dbb99499SAndroid Build Coastguard Worker
27*dbb99499SAndroid Build Coastguard Worker```bash
28*dbb99499SAndroid Build Coastguard Workersudo cpupower frequency-set --governor performance
29*dbb99499SAndroid Build Coastguard Worker```
30*dbb99499SAndroid Build Coastguard Worker
31*dbb99499SAndroid Build Coastguard WorkerAfter this you can verify that all CPUs are using the performance governor
32*dbb99499SAndroid Build Coastguard Workerby running this command:
33*dbb99499SAndroid Build Coastguard Worker
34*dbb99499SAndroid Build Coastguard Worker```bash
35*dbb99499SAndroid Build Coastguard Workercpupower frequency-info -o proc
36*dbb99499SAndroid Build Coastguard Worker```
37*dbb99499SAndroid Build Coastguard Worker
38*dbb99499SAndroid Build Coastguard WorkerThe benchmarks you subsequently run will have less variance.
39*dbb99499SAndroid Build Coastguard Worker
40*dbb99499SAndroid Build Coastguard Worker<a name="reducing-variance" />
41*dbb99499SAndroid Build Coastguard Worker
42*dbb99499SAndroid Build Coastguard Worker## Reducing Variance in Benchmarks
43*dbb99499SAndroid Build Coastguard Worker
44*dbb99499SAndroid Build Coastguard WorkerThe Linux CPU frequency governor [discussed
45*dbb99499SAndroid Build Coastguard Workerabove](user_guide#disabling-cpu-frequency-scaling) is not the only source
46*dbb99499SAndroid Build Coastguard Workerof noise in benchmarks.  Some, but not all, of the sources of variance
47*dbb99499SAndroid Build Coastguard Workerinclude:
48*dbb99499SAndroid Build Coastguard Worker
49*dbb99499SAndroid Build Coastguard Worker1. On multi-core machines not all CPUs/CPU cores/CPU threads run the same
50*dbb99499SAndroid Build Coastguard Worker   speed, so running a benchmark one time and then again may give a
51*dbb99499SAndroid Build Coastguard Worker   different result depending on which CPU it ran on.
52*dbb99499SAndroid Build Coastguard Worker2. CPU scaling features that run on the CPU, like Intel's Turbo Boost and
53*dbb99499SAndroid Build Coastguard Worker   AMD Turbo Core and Precision Boost, can temporarily change the CPU
54*dbb99499SAndroid Build Coastguard Worker   frequency even when the using the "performance" governor on Linux.
55*dbb99499SAndroid Build Coastguard Worker3. Context switching between CPUs, or scheduling competition on the CPU the
56*dbb99499SAndroid Build Coastguard Worker   benchmark is running on.
57*dbb99499SAndroid Build Coastguard Worker4. Intel Hyperthreading or AMD SMT causing the same issue as above.
58*dbb99499SAndroid Build Coastguard Worker5. Cache effects caused by code running on other CPUs.
59*dbb99499SAndroid Build Coastguard Worker6. Non-uniform memory architectures (NUMA).
60*dbb99499SAndroid Build Coastguard Worker
61*dbb99499SAndroid Build Coastguard WorkerThese can cause variance in benchmarks results within a single run
62*dbb99499SAndroid Build Coastguard Worker(`--benchmark_repetitions=N`) or across multiple runs of the benchmark
63*dbb99499SAndroid Build Coastguard Workerprogram.
64*dbb99499SAndroid Build Coastguard Worker
65*dbb99499SAndroid Build Coastguard WorkerReducing sources of variance is OS and architecture dependent, which is one
66*dbb99499SAndroid Build Coastguard Workerreason some companies maintain machines dedicated to performance testing.
67*dbb99499SAndroid Build Coastguard Worker
68*dbb99499SAndroid Build Coastguard WorkerSome of the easier and effective ways of reducing variance on a typical
69*dbb99499SAndroid Build Coastguard WorkerLinux workstation are:
70*dbb99499SAndroid Build Coastguard Worker
71*dbb99499SAndroid Build Coastguard Worker1. Use the performance governor as [discussed
72*dbb99499SAndroid Build Coastguard Workerabove](user_guide#disabling-cpu-frequency-scaling).
73*dbb99499SAndroid Build Coastguard Worker1. Disable processor boosting by:
74*dbb99499SAndroid Build Coastguard Worker   ```sh
75*dbb99499SAndroid Build Coastguard Worker   echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost
76*dbb99499SAndroid Build Coastguard Worker   ```
77*dbb99499SAndroid Build Coastguard Worker   See the Linux kernel's
78*dbb99499SAndroid Build Coastguard Worker   [boost.txt](https://www.kernel.org/doc/Documentation/cpu-freq/boost.txt)
79*dbb99499SAndroid Build Coastguard Worker   for more information.
80*dbb99499SAndroid Build Coastguard Worker2. Set the benchmark program's task affinity to a fixed cpu.  For example:
81*dbb99499SAndroid Build Coastguard Worker   ```sh
82*dbb99499SAndroid Build Coastguard Worker   taskset -c 0 ./mybenchmark
83*dbb99499SAndroid Build Coastguard Worker   ```
84*dbb99499SAndroid Build Coastguard Worker3. Disabling Hyperthreading/SMT.  This can be done in the Bios or using the
85*dbb99499SAndroid Build Coastguard Worker   `/sys` file system (see the LLVM project's [Benchmarking
86*dbb99499SAndroid Build Coastguard Worker   tips](https://llvm.org/docs/Benchmarking.html)).
87*dbb99499SAndroid Build Coastguard Worker4. Close other programs that do non-trivial things based on timers, such as
88*dbb99499SAndroid Build Coastguard Worker   your web browser, desktop environment, etc.
89*dbb99499SAndroid Build Coastguard Worker5. Reduce the working set of your benchmark to fit within the L1 cache, but
90*dbb99499SAndroid Build Coastguard Worker   do be aware that this may lead you to optimize for an unrealistic
91*dbb99499SAndroid Build Coastguard Worker   situation.
92*dbb99499SAndroid Build Coastguard Worker
93*dbb99499SAndroid Build Coastguard WorkerFurther resources on this topic:
94*dbb99499SAndroid Build Coastguard Worker
95*dbb99499SAndroid Build Coastguard Worker1. The LLVM project's [Benchmarking
96*dbb99499SAndroid Build Coastguard Worker   tips](https://llvm.org/docs/Benchmarking.html).
97*dbb99499SAndroid Build Coastguard Worker1. The Arch Wiki [Cpu frequency
98*dbb99499SAndroid Build Coastguard Workerscaling](https://wiki.archlinux.org/title/CPU_frequency_scaling) page.
99