Linux: Why does the CPU frequency fluctuate when using the performance governor?
I'm using a Debian 8 amd64 machine for benchmarking. During experimentation, I would like the CPU to operate at a fixed frequency (preferably the maximum possible). This will rule out the CPU clock speed as a source of variation in the results.
After some reading, it seems that the correct thing to do is to change the CPU governor to performance
, which is described here in the Linux kernel documentation:
The CPUfreq governor "performance" sets the CPU statically to the highest frequency within the borders of scaling_min_freq and scaling_max_freq.
Sadly, further details about scaling_min_freq
and scaling_max_freq
are not supplied. Hopefully it should not matter, as the CPU frequency used is the maximum value of the interval.
So I've enabled this governor using cpufreq-set:
$ cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor performance performance performance performance
And for good measure, I also disabled turbo boost mode in the bios:
$ cat /sys/devices/system/cpu/intel_pstate/no_turbo 1
Based on the above description of the performance governor, I would expect no fluctuation in the CPU clock speed. Yet if I repeatedly run cpufreq-info
, I see the clock speed fluctuating:
$ cpufreq-info | grep 'current CPU fr' current CPU frequency is 4.00 GHz. current CPU frequency is 3.99 GHz. current CPU frequency is 4.00 GHz. current CPU frequency is 4.00 GHz. $ cpufreq-info | grep 'current CPU fr' current CPU frequency is 4.00 GHz. current CPU frequency is 4.00 GHz. current CPU frequency is 4.00 GHz. current CPU frequency is 3.96 GHz. $ cpufreq-info | grep 'current CPU fr' current CPU frequency is 4.00 GHz. current CPU frequency is 4.00 GHz. current CPU frequency is 4.00 GHz. current CPU frequency is 3.94 GHz. $ cpufreq-info | grep 'current CPU fr' current CPU frequency is 4.01 GHz. current CPU frequency is 4.00 GHz. current CPU frequency is 4.00 GHz. current CPU frequency is 3.98 GHz.
Is this fluctuation due to hardware, the BIOS, the kernel, or some other factor? Is there a way to set the CPU frequency such that it doesn't fluctuate at all?
Solution 1:
After some experimentation, I think I can answer my own question.
As mentioned in this thread, on certain Intel hardware, there are two ways to manage the CPU frequency:
- Using pstate.
- Using regular ACPI.
When pstate is used, the BIOS has some say over the clock speed, and it seems that this is the source of the fluctuations.
You can force pstate off by appending intel_pstate=disable
to the kernel arguments (edit /etc/default/grub
and add the arg to GRUB_CMDLINE_LINUX_DEFAULT
. Finally run sudo update-grub
).
After doing this, the output of cpufreq-info
looks much different, and I also notice that a different set of CPU governors become available (e.g. ondemand
is now available).
Most importantly, after setting the governor to performance
, the clock speed is now fixed (in my case to 4.00GHz).
You can look in /sys/devices/system/cpu/cpu*/cpufreq/scaling_driver
to determine if pstate or ACPI is being used to scale the CPU. These files can assume the values acpi-cpufreq
or intel_pstate
.
Solution 2:
For contemporary Intel processors, the frequency is controlled by the processor itself and the P-states exposed to software are related to performance levels. The idea that frequency can be set to a single frequency is fiction for Intel Core processors. Even if the scaling driver selects a single P state the actual frequency the processor will run at is selected by the processor itself. [1]
[1] https://www.kernel.org/doc/Documentation/cpu-freq/intel-pstate.txt