19

When I do

sudo watch -n1 cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq

I get 1.8 - 2.7 GHz. It never goes above 2.7.

And when I do

watch -n1 "cat /proc/cpuinfo | grep MHz"

I get 768 MHz - 1.8 GHz. It never goes above 1.8.

Anyone know what is going on?

wulftone
  • 355

1 Answers1

21

Most CPU's now include the ability to adjust their speed to help in saving on battery/power usage. It's typically called CPU frequency scaling. The realtime speed of the CPU is reported by this:

$ sudo cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq

The absolute (max) CPU speed is being reported by this:

$ cat /proc/cpuinfo

Specifically this line:

model name  : Intel(R) Core(TM) i5 CPU       M 560  @ 2.67GHz

The line that shows cpu MHz doesn't show the maximum speed of your CPU. This value is your current speed. On a multi-core system such as an i7 or i5 you can see this with this command:

$ cat /proc/cpuinfo |grep MHz
cpu MHz     : 1199.000
cpu MHz     : 1199.000
cpu MHz     : 1199.000
cpu MHz     : 2667.000

You can however see the absolute (max) speed with this command:

$ lscpu 
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
CPU(s):                4
Thread(s) per core:    2
Core(s) per socket:    2
CPU socket(s):         1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 37
Stepping:              5
CPU MHz:               2667.000
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              3072K
NUMA node0 CPU(s):     0-3

NOTE: the number of cores that it has, NUMAS node0 CPU(s) is 4, i.e. 0,1,2, and 3.

CPU scaling & governoring?

The mode your system is in is called the scaling governor. Similar to a governor on a car. You can see which ones are available with this command:

$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
powersave ondemand userspace performance 

You can also see which one is currently active:

$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
ondemand

NOTE: The commands I'm showing only include the 1st cpu, cpu0. You can either substitute in a * in the path to see all the cores or you can selectively see cpu1, etc.

You can see the maximum & minimum CPU speeds available for your governor's profile:

$ sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
2667000
$ sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq 
1199000

More details are available in this article, titled: CPU frequency scaling in Linux with cpufreq.

So what about cpuinfo_cur_freq?

This parameter has more to do with the specification of the CPU and which profile it's currently in, rather than anything useful with respect to how the CPU is currently operating. For actual operational telemetry I'd use the scaling_* kernel tunables.

Example

I put the following script together to show the CPU Cores column-wise so it would be easier to see what the various Kernel tunables looked like:

#!/bin/bash

nthCore=$(lscpu|grep node0|cut -d"-" -f2)

for i in /sys/devices/system/cpu/cpu0/cpufreq/{cpuinfo,scaling}_*; do
  pname=$(basename $i)
  [[ "$pname" == *available* ]] || [[ "$pname" == *transition* ]] || \
  [[ "$pname" == *driver* ]]    || [[ "$pname" == *setspeed* ]] && continue
  echo "$pname: "
  for j in `seq 0 $nthCore`;do
    kparam=$(echo $i | sed "s/cpu0/cpu$j/")
    sudo cat $kparam
  done
done | paste - - - - - | column -t

When you run it you get the following output:

$ ./cpuinfo.bash
cpuinfo_cur_freq:  2667000   2667000   2667000   2667000
cpuinfo_max_freq:  2667000   2667000   2667000   2667000
cpuinfo_min_freq:  1199000   1199000   1199000   1199000
scaling_cur_freq:  2667000   2266000   1333000   2667000
scaling_governor:  ondemand  ondemand  ondemand  ondemand
scaling_max_freq:  2667000   2667000   2667000   2667000
scaling_min_freq:  1199000   1199000   1199000   1199000

You can see that the scaling_cur_freq tunable is showing a slowdown in core # 1 & 2.

slm
  • 369,824
  • If that were true, wouldn't /proc/cpuinfo report the same as cpuinfo_cur_freq? It clearly does not! The heart of my question still remains unsolved. I did uncover this tool that appears to somehow report "true frequency", but I'm not sure it works correctly. It provides some sources for its algorithm, but doesn't really provide a great explanation for the discrepancy. – wulftone Aug 23 '13 at 17:54
  • The lines such as /sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freq are showing the maximum speeds, even though they're name would imply current speed, this is the disconnect you're asking about, right? My system shows them this way as well. – slm Aug 23 '13 at 18:46
  • When you have frequency scaling turned on you should be using this to get the actual cpu frequencies: /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq – slm Aug 23 '13 at 19:14
  • For anyone who tries to run the script...you'll need to modify the paste command to have N+1 dashes, where N is the number of CPUs (logical cores) you are viewing. You'll also need to fix the first line. The simplest quick fix is to set it to N-1 (the number of cores, except they start with 0); the method in the script doesn't work at all for me on EL6, and wouldn't work right on a mutliple-CPU system. – Dan Pritts Mar 10 '16 at 03:30
  • @DanPritts - I believe I wrote that script on either a Fedora 14 or Fedora 19 system at the time, which is what I was using on my laptop where I wrote it. – slm Mar 10 '16 at 06:12
  • No worries - just wanted to pass on what i've figured out to the next person. This is a great answer with lots of useful information. – Dan Pritts Mar 10 '16 at 20:56
  • 2
    Note: Since Kernel 4.13, cat /proc/cpuinfo | grep MHz no longer returns the current clock speed. At the Kernel Bugzilla, they say it's intentional. See https://bugzilla.kernel.org/show_bug.cgi?id=197009. It's also mentioned here: https://www.phoronix.com/scan.php?page=news_item&px=Linux-4.13-Power-Management – Marc.2377 Oct 11 '17 at 03:14
  • 1