想要获取各逻辑核心的实时主频(kHz),直接读取 /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq 是唯一靠谱的办法。为啥呢?因为 /proc/cpuinfo 里的 cpu MHz 数据是来自内核缓存的,它有滞后性,而且只显示第一个核心的信息,根本没法体现多核异步调频的实际情况。

直接读 /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq 是唯一能拿到每个逻辑核心当前真实主频(单位 kHz)的方法,不需要额外工具,也不依赖缓存。
为什么不能只看 /proc/cpuinfo 的 cpu MHz
它确实会显示每个核心的频率,但这些值是从内核缓存中获取的,可能会有几十到几百毫秒的滞后。在高负载突变或快速降频的情况下(例如容器调度瞬间),cpu MHz 可能会停留在旧值上。更糟糕的是,grep "cpu MHz" /proc/cpuinfo | head -n 1 只会获取第一个核心的信息,这完全掩盖了多核异步调频的事实——在大小核架构下,cpu0 和 cpu8 的频率相差一倍是很常见的。
/sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq 怎么用
这个路径是内核 cpufreq 子系统暴露的实时接口,只要驱动加载成功(acpi-cpufreq、intel_cpufreq 或 amd-pstate),文件就可读,无需 root 权限:
- 逐核检查是否存在:
ls /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq,若报No such file or directory,说明该 CPU 未启用变频(常见于虚拟机、某些 ARM 板,或内核禁用了CONFIG_CPU_FREQ) - 读取全部核心当前频率:
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq,输出是一串数字(单位 kHz),比如2400000即 2.4 GHz - 实时监控(每秒刷新):
watch -n 1 'cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq 2>/dev/null | awk '{printf "%.2f GHz", $1/1000000} END{print ""}'',加2>/dev/null是为了过滤 offline 核心的报错
常见失效原因和对应检查项
不是所有环境都能读到这个文件,得先确认底层能力是否就绪:
- 某核心输出为空?先查它是否 online:
cat /sys/devices/system/cpu/online,若显示0-3,6-7,那cpu4和cpu5就不可用 - 整个
cpufreq目录不存在?运行dmesg | grep -i "cpu.*freq",看内核是否加载了频率驱动;没输出通常意味着 BIOS 关闭了 SpeedStep/Turbo 或内核参数加了intel_idle.max_cstate=1等抑制项 - 数值恒定不变?检查调频策略:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor,若为performance且scaling_max_freq等于cpuinfo_max_freq,那它就真锁死了
真正难搞的不是读数,而是判断「这个数到底信不信」——比如在 Intel 大小核混合架构上,cpu0(P-core)和 cpu16(E-core)的 scaling_cur_freq 单位相同,但功耗墙和温度阈值完全不同,必须分开看,不能取平均。