¿Por qué cpuinfo_cur_freq y / proc / cpuinfo informan números diferentes?

13

Cuando lo hago

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

Tengo 1.8 - 2.7 GHz. Nunca supera los 2.7.

Y cuando lo hago

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

Obtengo 768 MHz - 1.8 GHz. Nunca supera los 1,8.

Alguien sabe lo que está pasando?

wulftone
fuente

Respuestas:

14

La mayoría de las CPU ahora incluyen la capacidad de ajustar su velocidad para ayudar a ahorrar en el uso de batería / energía. Por lo general, se llama escala de frecuencia de CPU . Esto informa la velocidad en tiempo real de la CPU:

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

Esto informa la velocidad absoluta (máxima) de la CPU:

$ cat /proc/cpuinfo

Específicamente esta línea:

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

La línea que muestra cpu MHz no muestra la velocidad máxima de su CPU. Este valor es su velocidad actual. En un sistema multinúcleo como un i7 o i5, puede ver esto con este comando:

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

Sin embargo, puede ver la velocidad absoluta (máxima) con este comando:

$ 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

NOTA: el número de núcleos que tiene NUMAS node0 CPU(s)es 4, es decir, 0,1,2 y 3.

Escalado de CPU y gobernanza?

El modo en el que se encuentra su sistema se llama gobernador de escala. Similar a un gobernador en un automóvil. Puede ver cuáles están disponibles con este comando:

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

También puede ver cuál está actualmente activo:

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

NOTA: Los comandos que estoy mostrando sólo incluyen la primera CPU, cpu0. Puede sustituir en un *en la ruta para ver todos los núcleos o puede ver selectivamente cpu1, etc.

Puede ver las velocidades de CPU máximas y mínimas disponibles para el perfil de su gobernador:

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

Más detalles están disponibles en este artículo, titulado: Escalado de frecuencia de CPU en Linux con cpufreq .

Entonces, ¿qué pasa con cpuinfo_cur_freq?

Este parámetro tiene más que ver con la especificación de la CPU y el perfil en el que se encuentra actualmente, en lugar de algo útil con respecto a cómo está funcionando actualmente la CPU. Para la telemetría operativa real, usaría los scaling_*kernel tunables.

Ejemplo

Puse el siguiente script para mostrar los núcleos de la CPU en forma de columna para que sea más fácil ver cómo se veían los diferentes ajustables del kernel:

#!/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

Cuando lo ejecutas obtienes el siguiente resultado:

$ ./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

Puede ver que el scaling_cur_freqsintonizable muestra una desaceleración en los núcleos 1 y 2.

slm
fuente
Si eso fuera cierto, ¿no /proc/cpuinfoinformaría lo mismo que cpuinfo_cur_freq? Claramente no lo hace! El corazón de mi pregunta sigue sin resolverse. Descubrí esta herramienta que parece informar de alguna manera "frecuencia real", pero no estoy seguro de que funcione correctamente. Proporciona algunas fuentes para su algoritmo, pero en realidad no proporciona una gran explicación para la discrepancia.
wulftone
Las líneas que /sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freqmuestran las velocidades máximas, a pesar de que su nombre implicaría la velocidad actual, esta es la desconexión que estás preguntando, ¿verdad? Mi sistema también los muestra de esta manera.
slm
Cuando tiene activada la escala de frecuencia, debe usar esto para obtener las frecuencias de CPU reales:/sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
slm
2
Nota: desde Kernel 4.13, cat /proc/cpuinfo | grep MHzya no devuelve la velocidad actual del reloj . En el Kernel Bugzilla, dicen que es intencional. Ver bugzilla.kernel.org/show_bug.cgi?id=197009 . También se menciona aquí: phoronix.com/…
Marc.2377
1
... Revertido en Linux 4.14.rc8 .
Marc.2377