ლ(ಠ益ಠლ)

Ubuntu 14.04 LTS: Intel Xeon CPU Frequency Scaling

Following an installation of Ubuntu 14.04 LTS on a server using an Intel Xeon E3 chip, I observed that CPU performance was inconsistent with the reference specification.

Discovery

To confirm, I used a combination of data obtained from various operating system sources, specifically /proc/cpuinfo, i7z, and turbostat.

The Intel Xeon chip in question, has an operating frequency above 3.4GHz–/proc/cpuinfo indicated each logical core was running at an average of 800Mhz–use the following:

1
2
3
4
5
6
7
8
9
$ grep MHz /proc/cpuinfo
cpu MHz         : 800.078
cpu MHz         : 800.078
cpu MHz         : 799.394
cpu MHz         : 801.171
cpu MHz         : 800.078
cpu MHz         : 801.582
cpu MHz         : 800.078
cpu MHz         : 801.035

It’s likely your environment doesn’t have i7z installed. Install it from the repository.

1
2
3
4
5
6
7
8
9
# apt-get install i7z
$ apt-cache policy i7z
i7z:
  Installed: 0.27.2-2ubuntu1
  Candidate: 0.27.2-2ubuntu1
  Version table:
 *** 0.27.2-2ubuntu1 0
        500 http://us.archive.ubuntu.com/ubuntu/ trusty/universe amd64 Packages
        100 /var/lib/dpkg/status

The i7z utility has a number of known issues. This only reinforces the need to use multiple resources to ensure as accurate a reading of the CPU frequency as possible.

Once loaded, you will see that this utility is ncurses-based–compare the CPU’s “true” frequency with the “Actual Freq (Mult.)” (second column). For me, i7z once again reported an abysmal average of 800Mhz. Use [ctrl]+[c] to break out.

Finally, turbostat. The turbostat utility is available as a part of the linux-tools-common package. Using dpkg-query is especially helpful when dealing with unknown packages, to see what was installed.

1
2
3
4
5
6
7
8
9
# dpkg-query -L linux-tools-common
/.
/usr
/usr/bin
/usr/bin/x86_energy_perf_policy
/usr/bin/turbostat
/usr/bin/perf
/usr/bin/cpupower
# <cut>
1
2
3
4
5
6
7
8
9
$ apt-cache policy linux-tools-common
linux-tools-common:
  Installed: 3.13.0-57.95
  Candidate: 3.13.0-57.95
  Version table:
 *** 3.13.0-57.95 0
        500 http://us.archive.ubuntu.com/ubuntu/ trusty-updates/main amd64 Packages
        500 http://security.ubuntu.com/ubuntu/ trusty-security/main amd64 Packages
        100 /var/lib/dpkg/status

To use:

1
2
3
4
5
6
7
# The -S option limits output to a 1-line System Summary for each interval.
# The -i interval_sec option prints statistics every interval_sec seconds.  The default is 5 seconds.
$ turbostat -S -i 2
 Avg_MHz   %Busy Bzy_MHz TSC_MHz     SMI  CPU%c1  CPU%c3  CPU%c6  CPU%c7 CoreTmp  PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt
       0    0.06     826    3494       0    0.13    0.02    0.01   99.79      34      35    0.00    0.00    0.00    0.00    2.40    0.00    0.00
       0    0.05     814    3494       0    0.12    0.01    0.01   99.81      35      35    0.00    0.00    0.00    0.00    2.41    0.00    0.00
       1    0.06     814    3494       0    0.13    0.06    0.02   99.73      34      34    0.00    0.00    0.00    0.00    2.40    0.00    0.00

Compare “Bzy_MHz” to “TSC_Mhz”. As expected, Bzy_MHz was reporting an average of 800Mhz.

What do we do about it?

Disable ondemand

Ubuntu 14.04 LTS (still) uses upstart, therefore:

1
$ sudo update-rc.d ondemand disable

Install cpufrequtils

Similar to i7z, the environment doesn’t natively come with the cpufrequtils package. Install from the repository.

1
2
3
4
5
6
7
8
$ apt-cache policy cpufrequtils
cpufrequtils:
  Installed: 008-1
  Candidate: 008-1
  Version table:
 *** 008-1 0
        500 http://us.archive.ubuntu.com/ubuntu/ trusty/universe amd64 Packages
        100 /var/lib/dpkg/status

Create the config

1
2
3
4
5
$ touch /etc/default/cpufrequtils

$ cat <<EOF >> /etc/default/cpufrequtils
GOVERNOR="performance"
EOF

Restart

1
$ shutdown -rf now

Once the server has restarted, you can now use the first three (3) methods above to confirm that the CPU frequency scaling has been corrected.

In fact, there is now a fourth method available, specifically the utility “cpufreq-info” as we’re now using cpufrequtils.

1
2
3
4
5
6
7
8
9
10
# man cpufreq-info

$ cpufreq-info -f -m
3.50 GHz

$ cpufreq-info -w -m
3.50 GHz

$ cpufreq-info -p
800000 3900000 performance

Hope this helps!

Comments