Linux CPU频率文件详解:cpuinfo_*_freq 与 scaling_cur_freq
一、概述
在Linux系统中,/sys/devices/system/cpu/cpuX/cpufreq/ 目录下提供了多个用于查看和管理CPU频率的文件。其中,cpuinfo_max_freq、cpuinfo_min_freq 和 scaling_cur_freq 是最常被查看和对比的几个文件,它们分别代表了CPU的硬件能力 和实时运行状态。
1. 核心概念
这三个文件可以清晰地分为两类:
- 能力范围(静态信息) :
cpuinfo_max_freq和cpuinfo_min_freq - 当前状态(动态信息) :
scaling_cur_freq
2. 能力范围文件(静态)
这两个文件描述了CPU硬件的固有属性,定义了频率调节的绝对边界。
1.cpuinfo_min_freq
- 路径 :
/sys/devices/system/cpu/cpuX/cpufreq/cpuinfo_min_freq - 含义 :该CPU核心在硬件设计和固件支持下,能够稳定运行的最低频率。
- 特性 :
- 是一个静态的、不变的值。
- 代表了CPU的"设计规格"下限。
- 操作系统和调频策略不能将频率设置得比这个值更低。
2.cpuinfo_max_freq
- 路径 :
/sys/devices/system/cpu/cpuX/cpufreq/cpuinfo_max_freq - 含义 :该CPU核心在硬件设计和固件支持下,能够稳定运行的最高频率(通常指基频或最大睿频频率)。
- 特性 :
- 是一个静态的、不变的值。
- 代表了CPU的"设计规格"上限。
- 操作系统和调频策略不能将频率设置得比这个值更高。
三、当前状态文件(动态)
这个文件反映了CPU核心在运行时的实时状况。
scaling_cur_freq
- 路径 :
/sys/devices/system/cpu/cpuX/cpufreq/scaling_cur_freq - 含义 :显示该CPU核心此时此刻正在运行的实时频率。
- 特性 :
- 是一个动态的、实时变化的值。
- 其变化范围被严格限制在
[cpuinfo_min_freq, cpuinfo_max_freq]区间内。 - 直接反映了当前CPU调频器(governor)的决策结果。
- 会随着系统负载的变化而频繁波动。
四、类比理解
为了更好地理解,可以用汽车仪表盘进行类比:
| Linux CPUFreq 文件 | 汽车仪表盘类比 | 说明 |
|---|---|---|
cpuinfo_max_freq |
转速表红区 或 车辆设计的最高时速 | 引擎能力的理论上限,不能也不应超过。 |
cpuinfo_min_freq |
引擎能不熄火稳定运行的最低转速(怠速) | 引擎能够稳定工作的下限。 |
scaling_cur_freq |
当前时速表 | 显示了你此刻实际行驶的速度,会根据油门(负载)实时变化。 |
五、典型工作场景示例
假设某CPU核心(cpu0)的参数如下:
cpuinfo_min_freq=800000(800 MHz)cpuinfo_max_freq=3600000(3.6 GHz)
系统运行过程:
-
系统启动后空闲时:
scaling_cur_freq可能显示为800000(800 MHz)或略高,系统为省电将频率降至最低附近。
-
运行高负载任务时 (如编译软件
make -j4):scaling_cur_freq会迅速攀升,最终达到3600000(3.6 GHz),系统全力工作以追求性能。
-
任务结束后:
- 几秒钟内,
scaling_cur_freq会逐渐下降回800000(800 MHz)附近。
- 几秒钟内,
观察命令 :
你可以使用以下命令实时观察频率的动态变化:
bash
# 每秒刷新一次 cpu0 的当前频率
watch -n 1 "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"
六、扩展知识:scaling_*_freq 文件
在同一目录下,还有两个重要的管理性文件:
scaling_min_freq 和 scaling_max_freq
- 含义 :这是用户或系统策略允许 CPU调频器使用的软件频率范围。
- 特性 :
- 它们默认分别等于
cpuinfo_min_freq和cpuinfo_max_freq。 - 用户可以手动修改 这两个文件,来人为地限制CPU的频率范围,以实现特定的省电或降温目的。
- 例如,将
scaling_max_freq设置为2000000(2.0 GHz),那么即使CPU硬件支持3.6 GHz,其scaling_cur_freq最高也只能达到2.0 GHz。
- 它们默认分别等于
七、便捷脚本

bash
#!/bin/bash
# CPU频率监控脚本 - 带超限检测
# 使用方法: ./cpu_freq_check.sh [刷新间隔(秒)]
INTERVAL=${1:-2}
CPU_COUNT=$(grep -c "^processor" /proc/cpuinfo)
# 获取终端行数
TERM_LINES=$(tput lines)
show_header() {
# 使用转义序列清除屏幕并移动光标到左上角
printf "\033[2J\033[H"
echo "🔍 CPU频率监控 - 带超限检测"
echo "=================================================================================="
echo "时间: $(date "+%H:%M:%S") | 核心: ${CPU_COUNT} | 间隔: ${INTERVAL}s"
echo "=================================================================================="
}
# 初始化:第一次显示完整界面
first_run=true
check_freq_limits() {
local out_of_range_count=0
local scaling_limit_count=0
# 如果不是第一次运行,只移动光标到数据开始位置
if [ "$first_run" = false ]; then
# 移动到数据开始行(第6行)
printf "\033[6H"
else
echo "核心 当前频率 硬件范围 scaling范围 状态"
echo "------ ------------ -------------- -------------- ------------"
first_run=false
fi
for ((cpu=0; cpu<CPU_COUNT; cpu++)); do
cur_file="/sys/devices/system/cpu/cpu${cpu}/cpufreq/scaling_cur_freq"
min_file="/sys/devices/system/cpu/cpu${cpu}/cpufreq/cpuinfo_min_freq"
max_file="/sys/devices/system/cpu/cpu${cpu}/cpufreq/cpuinfo_max_freq"
scaling_min_file="/sys/devices/system/cpu/cpu${cpu}/cpufreq/scaling_min_freq"
scaling_max_file="/sys/devices/system/cpu/cpu${cpu}/cpufreq/scaling_max_freq"
# 移动到该CPU行的开始位置
printf "\033[%d;1H" $((8 + cpu))
if [ -f "$cur_file" ]; then
current=$(cat "$cur_file" 2>/dev/null)
min_freq=$(cat "$min_file" 2>/dev/null)
max_freq=$(cat "$max_file" 2>/dev/null)
scaling_min=$(cat "$scaling_min_file" 2>/dev/null)
scaling_max=$(cat "$scaling_max_file" 2>/dev/null)
current_mhz=$((current/1000))
min_mhz=$((min_freq/1000))
max_mhz=$((max_freq/1000))
scaling_min_mhz=$((scaling_min/1000))
scaling_max_mhz=$((scaling_max/1000))
# 检查状态
status="✅ 正常"
color="\033[32m" # 绿色 - 正常
# 检查是否超出硬件范围
if [ $current -lt $min_freq ] || [ $current -gt $max_freq ]; then
color="\033[31m" # 红色 - 超出硬件范围
status="⚠️ 硬件超限"
out_of_range_count=$((out_of_range_count + 1))
# 检查是否超出scaling范围
elif [ $current -lt $scaling_min ] || [ $current -gt $scaling_max ]; then
color="\033[33m" # 黄色 - 超出scaling范围
status="⚠️ 缩放超限"
scaling_limit_count=$((scaling_limit_count + 1))
fi
# 清除当前行并输出新内容
printf "\033[KCPU%-2d ${color}%4d MHz\033[0m %4d-%-4d MHz %4d-%-4d MHz ${status}\n" \
$cpu $current_mhz $min_mhz $max_mhz $scaling_min_mhz $scaling_max_mhz
else
# 清除当前行并输出离线状态
printf "\033[KCPU%-2d -- 离线 -- -- 离线 -- -- 离线 -- ⚫ 离线\n" $cpu
fi
done
# 移动到统计信息行
local stats_line=$((8 + CPU_COUNT))
printf "\033[%d;1H" $stats_line
printf "\033[K=================================================================================="
local warning_count=$((out_of_range_count + scaling_limit_count))
# 更新统计信息行
printf "\033[%d;1H" $((stats_line + 1))
printf "\033[K" # 清除行
if [ $warning_count -gt 0 ]; then
if [ $out_of_range_count -gt 0 ]; then
printf "\033[K🚨 严重: ${out_of_range_count}个核心频率超出硬件范围!\n"
fi
if [ $scaling_limit_count -gt 0 ]; then
printf "\033[K⚠️ 警告: ${scaling_limit_count}个核心频率超出scaling范围!\n"
fi
else
printf "\033[K✅ 所有核心频率均在正常范围内\n"
fi
# 更新额外信息行
local info_line=$((stats_line + 2))
local current_line=$info_line
# 检查Turbo Boost状态
if [ -f "/sys/devices/system/cpu/intel_pstate/no_turbo" ]; then
turbo_status=$(cat /sys/devices/system/cpu/intel_pstate/no_turbo)
if [ "$turbo_status" = "0" ]; then
printf "\033[%d;1H" $current_line
printf "\033[K💡 提示: Intel Turbo Boost 已启用"
current_line=$((current_line + 1))
fi
fi
if [ -f "/sys/devices/system/cpu/cpufreq/boost" ]; then
boost_status=$(cat /sys/devices/system/cpu/cpufreq/boost)
if [ "$boost_status" = "1" ]; then
printf "\033[%d;1H" $current_line
printf "\033[K💡 提示: CPU频率加速已启用"
current_line=$((current_line + 1))
fi
fi
# 显示scaling governor信息
governor_file="/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
if [ -f "$governor_file" ]; then
governor=$(cat "$governor_file" 2>/dev/null)
printf "\033[%d;1H" $current_line
printf "\033[K🎛️ 当前调频策略: ${governor}"
current_line=$((current_line + 1))
fi
# 显示可用调频策略信息
available_governors_file="/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors"
if [ -f "$available_governors_file" ]; then
available_governors=$(cat "$available_governors_file" 2>/dev/null)
printf "\033[%d;1H" $current_line
printf "\033[K📋 可用调频策略: ${available_governors}"
current_line=$((current_line + 1))
fi
# 显示系统负载
if command -v uptime >/dev/null 2>&1; then
load_avg=$(uptime | awk -F'load average:' '{print $2}')
printf "\033[%d;1H" $current_line
printf "\033[K📊 系统负载:${load_avg}"
current_line=$((current_line + 1))
fi
# 清除剩余的可能旧内容
for ((line=current_line; line<=TERM_LINES; line++)); do
printf "\033[%d;1H" $line
printf "\033[K"
done
# 移动光标到最后,避免闪烁
printf "\033[%d;1H" $TERM_LINES
}
# 获取CPU型号
CPU_MODEL=$(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 | sed 's/^ *//')
# 初始显示
show_header
echo "CPU: ${CPU_MODEL}"
echo "开始监控,按 Ctrl+C 停止..."
echo "核心 当前频率 硬件范围 scaling范围 状态"
echo "------ ------------ -------------- -------------- ------------"
trap 'printf "\033[?25h\033[%d;1H\n监控结束\n" $((8 + CPU_COUNT + 10)); exit 0' INT TERM
# 显示光标并设置退出时恢复
printf "\033[?25l"
while true; do
check_freq_limits
sleep $INTERVAL
done