一、查看当前调频驱动(先确认环境)
先执行:
cpupower frequency-info
重点看:
driver: intel_pstate 或 acpi-cpufreq
情况 A(最常见,14 代一般是):
driver: intel_pstate
用 intel_pstate 控制(推荐方式)
1️⃣ 设为 performance 模式(防止自动降频)
sudo cpupower frequency-set -g performance
检查:
cpupower frequency-info | grep governor
应为:
governor: performance
2️⃣ 关闭节能模式(允许跑满频)
echo 0 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo
cat /sys/devices/system/cpu/intel_pstate/no_turbo
(0 = 开 Turbo,1 = 禁用 Turbo)
情况 B:
driver: acpi-cpufreq
传统方式
二、分别控制 P/E 核(实验级)
1️⃣ 看核心拓扑
lscpu -e
输出
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE MAXMHZ MINMHZ MHZ
0 0 0 0 0:0:0:0 yes 4700.0000 800.0000 2500.0249
1 0 0 0 0:0:0:0 yes 4700.0000 800.0000 2500.0000
2 0 0 1 4:4:1:0 yes 4700.0000 800.0000 2500.0000
3 0 0 1 4:4:1:0 yes 4700.0000 800.0000 2500.0000
4 0 0 2 8:8:2:0 yes 4700.0000 800.0000 2500.0249
5 0 0 2 8:8:2:0 yes 4700.0000 800.0000 2500.0000
6 0 0 3 12:12:3:0 yes 4700.0000 800.0000 2500.0000
7 0 0 3 12:12:3:0 yes 4700.0000 800.0000 2500.0000
8 0 0 4 16:16:4:0 yes 4700.0000 800.0000 2500.0249
9 0 0 4 16:16:4:0 yes 4700.0000 800.0000 2499.9741
10 0 0 5 20:20:5:0 yes 4700.0000 800.0000 2500.0000
11 0 0 5 20:20:5:0 yes 4700.0000 800.0000 2500.0000
12 0 0 6 28:28:7:0 yes 3500.0000 800.0000 1799.9860
13 0 0 7 29:29:7:0 yes 3500.0000 800.0000 1799.9969
14 0 0 8 30:30:7:0 yes 3500.0000 800.0000 1800.0389
15 0 0 9 31:31:7:0 yes 3500.0000 800.0000 1799.9760
2️⃣ 分组锁频(示例)
- cpu0-11 = P 核
- cpu12-15 = E 核
锁定频率范围:
P 核:
sudo cpupower -c 0-11 frequency-set -d 2.5GHz -u 4.7GHz
E 核:
sudo cpupower -c 12-15 frequency-set -d 1.8GHz -u 3.5GHz
锁定固定频率(比如Base频率):
P 核:
sudo cpupower -c 0-11 frequency-set -d 2.5GHz -u 2.5GHz
E 核:
sudo cpupower -c 12-15 frequency-set -d 1.8GHz -u 1.8GHz
⚠️ 注意:
- 有些主板 BIOS/内核会无视这个
- intel_pstate 下可能不完全生效
三、验证是否生效
实时看每个核心频率(最直观)
推荐方式一(最简单):
watch -n1 "grep MHz /proc/cpuinfo"
每 1 秒刷新一次,看到类似:
Every 1.0s: grep MHz /proc/cpuinfo
cpu MHz : 2500.025
cpu MHz : 800.000
cpu MHz : 2500.000
cpu MHz : 2500.000
cpu MHz : 2500.000
cpu MHz : 2500.000
cpu MHz : 2500.025
cpu MHz : 2500.000
cpu MHz : 2500.025
cpu MHz : 2500.000
cpu MHz : 2500.000
cpu MHz : 2500.000
cpu MHz : 1799.939
cpu MHz : 1455.954
cpu MHz : 1800.040
cpu MHz : 1799.981
没有完全锁定现象和原因
现在其实是"基本成功的",看数据:
2500 MHz → P核 Base ✅
1800 MHz → E核 Base ✅
800 MHz → 空闲睡眠态 ⚠️
1455 MHz → 中间态 ⚠️
说明:
👉 你的锁频 80% 成功了
👉 剩下 20% 是省电机制
从上面的输出可以看到,cpu并没有被真正锁定,这是 正常现象 + intel_pstate 的一个"坑点",不是你没配好。先直接告诉你结论,再解释原因和解决办法。
一句话结论
你看到的:
800 MHz
1455 MHz
👉 不是锁频失败,而是:
在「空闲 / C-State / 省电状态」下,
Intel CPU 会短暂进入深度节能模式 ,绕过了 cpupower 的最低频率限制。
所以:
✔️ 有负载 → 回到 2.5 / 1.8 GHz
✔️ 没负载 → 掉到 800MHz(省电)
这是设计行为,不是 bug。
二、为什么会这样?(原理)
在 intel_pstate 下,有 3 套机制同时在管你 CPU:
1️⃣ P-State(频率调节)刚才控制的是这个
2.5GHz ~ 4.7GHz
2️⃣ C-State(睡眠状态)现在没关 ❗
C1 / C3 / C6 / C10 ...
进入深度 C-State 后:
CPU 几乎"半睡眠",频率显示会掉到:
800MHz 左右
3️⃣ HWP(硬件自控)14代默认开启
CPU 自己决定省不省电。
现在的状态是:
| 模块 | 状态 |
|---|---|
| P-State | ✅ 你控制住了 |
| C-State | ❌ 还在乱进 |
| HWP | ✅ 自动 |
所以会出现你看到的混合频率。
彻底锁定,不掉到 800MHz(实验模式)
⚠️ 注意:下面操作 = 更耗电 + 更热 + 风扇更响,只建议实验时用。
🔧 方法一(推荐):关闭深度 C-State(最有效),只用方法一一般就可以
for i in /sys/devices/system/cpu/cpu*/cpuidle/state*/disable; do
echo 1 | sudo tee $i
done
含义:
1 = 禁用该睡眠态
执行后再看:
watch -n1 "grep MHz /proc/cpuinfo"
800MHz 基本会消失。
Every 1.0s: grep MHz /proc/cpuinfo
cpu MHz : 2499.974
cpu MHz : 2500.000
cpu MHz : 2500.025
cpu MHz : 2500.025
cpu MHz : 2500.025
cpu MHz : 2500.025
cpu MHz : 2465.597
cpu MHz : 2465.567
cpu MHz : 2500.000
cpu MHz : 2500.000
cpu MHz : 2500.000
cpu MHz : 2499.974
cpu MHz : 1800.011
cpu MHz : 1799.984
cpu MHz : 1800.024
cpu MHz : 1799.974
🔧 方法二:禁用 HWP(硬件自动调度)
查看:
cat /sys/devices/system/cpu/intel_pstate/hwp_dynamic_boost
如果是 1,关掉:
echo 0 | sudo tee /sys/devices/system/cpu/intel_pstate/hwp_dynamic_boost
(部分机器没有这个文件)
🔧 方法三(终极):内核启动参数(最干净)
如果你长期做能耗实验,建议用这个。
编辑 grub:
sudo nano /etc/default/grub
找到:
GRUB_CMDLINE_LINUX_DEFAULT
改成:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_idle.max_cstate=0 processor.max_cstate=1"
更新:
sudo update-grub
sudo reboot
含义:
| 参数 | 作用 |
|---|---|
| intel_idle.max_cstate=0 | 禁深睡 |
| processor.max_cstate=1 | 限制睡眠 |
重启后基本不会再看到 800MHz。
四、完整脚本
#!/bin/bash
# ==============================
# CPU Mode Switch Script
# For Intel 14th Gen Hybrid CPU
# ==============================
# Check root
if [ "$EUID" -ne 0 ]; then
echo "❌ Please run as root: sudo ./cpu_mode.sh"
exit 1
fi
# P/E core ranges (adjust if needed)
P_CORES="0-5"
E_CORES="6-9"
P_BASE="2.5GHz"
E_BASE="1.8GHz"
P_MAX="4.7GHz"
E_MAX="3.5GHz"
LOW="800MHz"
echo "=============================="
echo " CPU Frequency Control Menu"
echo "=============================="
echo "0 = Power Save (800MHz)"
echo "1 = Base Lock (P=2.5G E=1.8G)"
echo "2 = Turbo Lock (P=4.7G E=3.5G)"
echo "3 = Unrestricted (Dynamic/OS Default)"
echo "=============================="
read -p "Select mode (0/1/2/3): " MODE
# Performance governor (Default for locked modes)
cpupower frequency-set -g performance >/dev/null
# Enable turbo
echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
# Disable C-States (Default for locked modes to prevent dropping)
for i in /sys/devices/system/cpu/cpu*/cpuidle/state*/disable; do
echo 1 > "$i"
done
case "$MODE" in
0)
echo "👉 Power Save Mode (800MHz)"
cpupower -c $P_CORES frequency-set -d $LOW -u $LOW
cpupower -c $E_CORES frequency-set -d $LOW -u $LOW
;;
1)
echo "👉 Base Lock Mode"
cpupower -c $P_CORES frequency-set -d $P_BASE -u $P_BASE
cpupower -c $E_CORES frequency-set -d $E_BASE -u $E_BASE
;;
2)
echo "👉 Turbo Lock Mode"
cpupower -c $P_CORES frequency-set -d $P_MAX -u $P_MAX
cpupower -c $E_CORES frequency-set -d $E_MAX -u $E_MAX
;;
3)
echo "👉 Unrestricted Mode (OS Dynamic Control)"
# 恢复动态调度器 (Intel pstate 默认的动态调度是 powersave,若不支持则 fallback 到 ondemand)
cpupower frequency-set -g powersave >/dev/null 2>&1 || cpupower frequency-set -g ondemand >/dev/null 2>&1
# 重新启用 C-States,允许核心在空闲时自然降频和休眠
for i in /sys/devices/system/cpu/cpu*/cpuidle/state*/disable; do
echo 0 > "$i"
done
# 将频率范围彻底放宽到最大可用区间
cpupower -c $P_CORES frequency-set -d $LOW -u $P_MAX
cpupower -c $E_CORES frequency-set -d $LOW -u $E_MAX
;;
*)
echo "❌ Invalid input"
exit 1
;;
esac
echo
echo "✅ Configuration Applied"
echo "Monitoring frequency (Ctrl+C to exit)..."
echo
watch -n1 "grep MHz /proc/cpuinfo"
这个脚本支持 3 种模式:
| 输入 | 模式 | 行为 |
|---|---|---|
| 0 | 💤 省电模式(800MHz) | 全核锁 800MHz |
| 1 | ⚙️ Base 锁频 | P=2.5GHz / E=1.8GHz |
| 2 | 🚀 Max 锁频 Turbo 模式 | P=4.7GHz / E=3.5GHz |
同时会:
✔️ 切 performance governor
✔️ 打开 Turbo
✔️ 关闭 C-State(防 800MHz 漂移)
✔️ 最后实时监控频率
chmod +x cpu_mode.sh
sudo ./cpu_mode.sh
然后你会看到:
0 = Power Save
1 = Base Lock
2 = Turbo Lock
Select mode:
输入 0 / 1 / 2 回车即可。
五、如果只想部分cpu生效
关闭不需要的核心,注意大多数时候,0号cpu不能关闭;
当你通过 echo 0 > online 将核心"移除"(Offline/下线)后,这个核心不仅在操作系统层面"消失"了,在物理硬件层面也会进入极深度的休眠状态。
具体来说,会发生以下几个物理和逻辑层面的变化:
-
触发极深 C-State (如 C6/C7 甚至更深)
在 Linux 内核完成任务迁移后,它会向该核心发送一个特定的休眠指令(通常是 MWAIT 或 HLT 指令)。这会直接触发 CPU 的硬件电源管理模块(PCU),强制该核心进入它能支持的最深休眠状态(Deep C-State)。
-
硬件级断电与断钟 (Power Gating & Clock Gating)
进入深度休眠后,主板和 CPU 内部的微控制器会执行以下操作:
停止时钟信号 (Clock Gating):核心的频率直接降为 0,不再进行任何时钟周期的翻转。
切断供电 (Power Gating):现代 Intel 架构支持单核电源门控(Per-Core Power Gating/VCC 隔离)。这个被移除的核心的供电会被物理切断,此时它的功耗无限接近于 0 瓦。
- 清空并关闭私有缓存 (L1 / L2 Cache Flush)
在进入深度休眠前,该核心的 L1 和 L2 私有缓存(如果是 P-Core)里的数据会被全部写回主存或 L3 共享缓存。然后,它的私有缓存也会被断电,以彻底消除漏电流带来的静态功耗。
⚠️ 一个重要的物理局限("连带责任")
虽然你移除的那个核心自己确确实实"睡死了"(功耗为0),但这并不意味着这部分面积一点电都不耗。
因为在 Intel 的架构中,多个核心共享着 L3 缓存和 Ring Bus(环形总线)。
如果你留下的核心(比如 0 号 P-Core)正在以 4.7GHz 的睿频狂奔,那么整个 Ring Bus 和 L3 缓存依然需要维持极高的电压和频率。
所以,尽管被拔除的核心本身不耗电,但为了支撑依然在线的那个核心,CPU 整体封装(Package) 依然会保持一定的基础功耗,无法进入更深度的 Package C-State(如 PC8/PC10)。
简而言之:被移除的核心本身会进入类似"拔电源"的物理级深度休眠,这对降低整体发热和功耗非常有帮助。
#!/bin/bash
# ==============================
# CPU Hybrid Core Control Script
# 支持指定核心工作,其余核心下线
# ==============================
if [ "$EUID" -ne 0 ]; then
echo "❌ 请以 root 权限运行: sudo $0"
exit 1
fi
# 核心定义
ALL_CORES=(0 1 2 3 4 5 6 7 8 9)
P_CORES=(0 1 2 3 4 5)
E_CORES=(6 7 8 9)
# 频率参数 (请根据具体型号调整,单位通常为 GHz 或 MHz)
P_MAX="4.7GHz"; P_BASE="2.5GHz"; LOW="800MHz"
E_MAX="3.5GHz"; E_BASE="1.8GHz"
echo "--------------------------------------"
echo "步骤 1: 选择工作核心 (例如: 0,1,6)"
echo "--------------------------------------"
read -p "请输入要保留的核心编号 (空格分隔): " -a ACTIVE_CORES
if [ ${#ACTIVE_CORES[@]} -eq 0 ]; then
echo "❌ 未输入核心,退出。"
exit 1
fi
echo "--------------------------------------"
echo "步骤 2: 选择频率模式"
echo "--------------------------------------"
echo "0 = Lowest (800MHz)"
echo "1 = Base Lock (P=2.5G, E=1.8G)"
echo "2 = Turbo Lock (P=4.7G, E=3.5G)"
read -p "选择模式 (0/1/2): " MODE
# --- 执行核心上下线控制 ---
echo "⚙️ 正在配置核心状态..."
# 先尝试启用所有核心,防止逻辑冲突
for i in "${ALL_CORES[@]}"; do
if [ "$i" -eq 0 ]; then continue; fi # CPU0 通常不允许下线
echo 1 > /sys/devices/system/cpu/cpu$i/online 2>/dev/null
done
# 禁用不在 ACTIVE_CORES 列表中的核心
for i in "${ALL_CORES[@]}"; do
if [ "$i" -eq 0 ]; then continue; fi
IS_ACTIVE=false
for active in "${ACTIVE_CORES[@]}"; do
if [ "$i" -eq "$active" ]; then IS_ACTIVE=true; break; fi
done
if [ "$IS_ACTIVE" = false ]; then
echo 0 > /sys/devices/system/cpu/cpu$i/online
echo "💤 核心 $i 已进入休眠 (Offline)"
fi
done
# --- 执行频率控制 ---
# 设置为 performance 模式
cpupower frequency-set -g performance >/dev/null
case "$MODE" in
0)
echo "🚀 模式: Lowest (800MHz)"
for i in "${ACTIVE_CORES[@]}"; do
cpupower -c $i frequency-set -d $LOW -u $LOW >/dev/null
done
;;
1)
echo "🚀 模式: Base Lock"
for i in "${ACTIVE_CORES[@]}"; do
if [[ " ${P_CORES[@]} " =~ " $i " ]]; then
cpupower -c $i frequency-set -d $P_BASE -u $P_BASE >/dev/null
else
cpupower -c $i frequency-set -d $E_BASE -u $E_BASE >/dev/null
fi
done
;;
2)
echo "🚀 模式: Turbo Lock"
echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
for i in "${ACTIVE_CORES[@]}"; do
if [[ " ${P_CORES[@]} " =~ " $i " ]]; then
cpupower -c $i frequency-set -d $P_MAX -u $P_MAX >/dev/null
else
cpupower -c $i frequency-set -d $E_MAX -u $E_MAX >/dev/null
fi
done
;;
*)
echo "❌ 无效输入"
exit 1
;;
esac
echo "✅ 配置完成!"
echo "当前在线核心: $(grep "processor" /proc/cpuinfo | wc -l)"
watch -n1 "grep MHz /proc/cpuinfo"
使用方式:
x@ubuntu:~$ sudo ./cpu_mode_can_sleep.sh
--------------------------------------
步骤 1: 选择工作核心 (例如: 0,1,6)
--------------------------------------
请输入要保留的核心编号 (空格分隔): 1 2
--------------------------------------
步骤 2: 选择频率模式
--------------------------------------
0 = Lowest (800MHz)
1 = Base Lock (P=2.5G, E=1.8G)
2 = Turbo Lock (P=4.7G, E=3.5G)
选择模式 (0/1/2): 2
⚙️ 正在配置核心状态...
💤 核心 3 已进入休眠 (Offline)
💤 核心 4 已进入休眠 (Offline)
💤 核心 5 已进入休眠 (Offline)
💤 核心 6 已进入休眠 (Offline)
💤 核心 7 已进入休眠 (Offline)
💤 核心 8 已进入休眠 (Offline)
💤 核心 9 已进入休眠 (Offline)
🚀 模式: Turbo Lock
✅ 配置完成!
当前在线核心: 3
Every 1.0s: grep MHz /proc/cpuinfo
cpu MHz : 4510.876
cpu MHz : 2445.370
cpu MHz : 2460.407
Core 0 的频率
在测试场景下(只用 2 个 E-Core 跑满负载,Core 0 空闲),Core 0 的频率会处于一种极端的两极分化状态:
1. 物理层面的真实频率:0 MHz(99% 的时间)
正如前面提到的,当 Core 0 因为没有任务而进入 C-State 深度休眠(如 C6/C7)时,它的内部时钟信号会被硬件级切断(Clock Gating)。
- 此时没有时钟周期翻转,它的真实物理频率就是 0 MHz。
- 它在静静地等待下一个硬件中断将它唤醒。
2. 唤醒瞬间的频率:最高允许频率(1% 的时间)
当鼠标动了一下、网卡收到数据,或者系统定时器滴答了一下,Core 0 会被瞬间唤醒(耗时几微秒)。
因为我们在 cpu_manager.sh 中执行了 cpupower frequency-set -g performance(这个命令如果不加 -c 参数,默认会把所有 Online 核心的调度器都设为 performance 性能模式),所以:
- 如果你的脚本处于 Mode 2 (Turbo 模式) :Core 0 一旦醒来,硬件(Intel HWP)会立刻让它飙升到 4.7GHz (P-Core 最大睿频),用最快的速度把这个后台小任务处理完,然后秒回 0 MHz 继续睡。这是 Intel 架构典型的"Race to Sleep(加速睡眠)"策略。
- 如果你的脚本处于 Mode 1 (Base 模式) :由于全局禁用了睿频(
no_turbo=1),它唤醒时最高只能跑到 2.5GHz (基础频率)。
3. 系统监控工具显示的频率:通常是 800 MHz 或最后一次唤醒的频率
如果你在这个时候打开另一个终端,输入 watch -n1 "grep MHz /proc/cpuinfo",你看到的 Core 0 频率大概率会停留在 800 MHz(Intel 14代最低的 P-State 频率),或者偶尔跳动到高频。
为什么不是 0 MHz 呢?