Linux电源管理策策略——Intel CPU
针对 Intel 的 CPU 电源策略的考虑:
- P-State,C-State 分别意味着什么?
- 为什么调整 CPU 的 P-State 并添加负载,CPU 状态会调整回来。
- 是 Linux 调整,还是 CPU 自己调整的,C-State 是 OS 在调整
1 基本概念
1.1 C-State and P-State
P-state 是指处理器状态(processor state),也被称为处理器频率或电压状态。它指的是处理器在不同工作负载下采用的电压和频率的组合,以达到最佳的性能和能耗平衡。
C-state 是指 CPU 状态(CPU state),也被称为睡眠状态。它指的是处理器在空闲或轻负载状态下进入的低功耗状态,以节省能量并减少发热,延长处理器的寿命。C-state 的级别越高,功耗越低,但唤醒需要更多的时间和资源。
1.2 Linux 功耗管理策略
1.2.1 管理策略
在 kernel doc 的Power Management Strategies里面,intel 的开发人员介绍了当前 Linux kernel 支持的两类高层的功耗管理策略:
- 系统范围的功耗管理(System-Wide power management)
- 工作状态的功耗管理(Working-State Power Management)
他举了一个例子,这两个电源策略负责处理不同的工作场景,比如离开笔记本电脑(关闭盖子)时,就会启动 System-Wide power management 策略控制系统进入睡眠状态,让大部分组件空闲下来,降低系统功耗。而在打开笔记本进行工作时应当用 Working-State Power Management 来动态管理功耗变换。
1.2.1 System-Wide power management
这个策略主要在管理电脑的睡眠状态,根据文档介绍,在目前 Linux kernel 中支持4 种系统睡眠状态,包含休眠和 3 种系统挂起的变体。
- suspend-to-idle,这个模式就是通过冻结用户空间,暂停计时并将所有 IO 设备置于低功耗状态。
- standby,除了冻结用户空间,暂停计时并将所有 IO 设备置于低功耗状态之外,nonboot 的 cpu 将会 offline,在转换到这个状态后所有底层的系统函数将会暂停/挂起。因此这个状态会更加解决能耗,但恢复到工作状态的时间就会更久了。
- suspend-to-ram,这个状态下,设备和 CPU 的状态都被写入 RAM,系统所有的组都会处于低功耗状态,内核的控制权将会在转换到从 S2RAM 后交回 BIOS。
- hibernation,休眠状态下,内核将还会停止所有系统活动,并创建内存快照存入磁盘。写入磁盘后,系统进入目标低功耗状态或者关闭电源。如果需要唤醒,就需要重新引导内行人,并加载内存快照恢复到休眠前。
1.2.2 Working-State Power Management
这个管理模式下主要分为两个部分CPU Idle Time Management
和CPU Performance Scaling
。
1.2.2.1 CPU Idle Time Management
这个就是 C-State 的概念吧
这里文档中指出了 CPU Idle 的概念,对于类似英特尔的 CPU 的超线程技术,一个核心中可能存在多个硬件线程(Logical CPU,或简称 CPU),如果某核心中一个线程被要求进入空闲状态,那么该线程(CPU)就会进入空闲状态,除非同一个核心内的其他硬件线程也要求进入空闲状态,那么整个核心都会空闲,否则整个核心中不会发生其他状况。
空闲循环任务
正常的 CPU 进入空闲状态,就给 CPU 一个空闲循环任务。空闲循任务的执行需要两个主要步骤:
- 调用
CPUIdle
子系统去选择一个 idle state 给 CPU 进入。 - 调用
CPUIdle
子系统的一个代码模块(驱动模块),实际请求处理器硬件进入governor
选择进入的状态。governor 的作用是找到最适合当前条件的空闲状态。
Tickless
简单来说,CPU 会配置一个 scheduler tick 作为计时器来决定 CPU 调度的时分共享策略。意味着每个任务都会被分配一段 CPU 时间来运行代码,时间结束后就会切换热舞,空闲 CPU 的空闲任务来说这是有问题的。因为计时器的触发时相对频繁的,而计时器频繁地请求目标 CPU 唤醒并再次进入空闲状态,这会导致 CPU 的空闲状态不超过 tick 周期,这样会发生能耗浪费。内核中可以配置 tickless 参数让 CPU 空闲时停止 tick 触发来使得系统更节能。如果系统支持 tickless,则使用menu
governor 否则使用ladder
。
一般有 4 中可用的CPUIdle
governors,分别是menu
,TEO
,ladder
和haltpoll
。
1.2.2.2 CPU Performance Scaling
这个概念就是指的是 P-State,指的是让 CPU 以多种不同的时钟频率和电压配置运行。
Linux 内核中用CPUFreq
子系统支持 CPU 的性能缩放,它包含了 3 个层次的代码: the core, scaling governors 和 scaling drivers。
- the core,提供了公共的用户接口和基础代码,定义了基本框架。
- scaling governors, 实现估计 CPU 容量的算法。
- scaling drivers 直接和硬件交互,根据 scaling governors 的请求改变 CPU 的 P-State。
2 状态控制和负载控制
docker run -it --privileged --hostname cpuload --name cpuload ubuntu:20.04 /bin/bash
# 安装modprobe
apt-get install kmod -y
# 安装cpu-power指令,https://manpages.debian.org/testing/linux-cpupower/index.html
apt-get install linux-tools-common linux-tools-$(uname -r)
# cpupower --help
/sys/devices/system/cpu/cpu<N>/cpuidle/
2.1 CPUIdle (C-State)
Ubuntu
cpu-idle 的控制启用和禁用 c-state,不能指定 cpu 立刻进入某个 c-state
-
idle-info
# --cpu 指定cpu cpupower --cpu 0 idle-info
结果输出
latency
,Exit latency of the idle state in microseconds.usage
,Total number of times the hardware has been asked by the given CPU to enter this idle state.
CPUidle driver: intel_idle CPUidle governor: menu analyzing CPU 0: Number of idle states: 4 Available idle states: POLL C1 C1E C6 POLL: Flags/Description: CPUIDLE CORE POLL IDLE Latency: 0 Usage: 4338722 Duration: 32917820 C1: Flags/Description: MWAIT 0x00 Latency: 2 Usage: 202782261 Duration: 9259454371 C1E: Flags/Description: MWAIT 0x01 Latency: 10 Usage: 126552375 Duration: 31762469023 C6: Flags/Description: MWAIT 0x20 Latency: 133 Usage: 708330302 Duration: 3409706493833
-
idle-set
# 启用所有的idle-sate cpupower --cpu 15 idle-set --enable-all # 禁用 POLL cpupower --cpu 15 idle-set --disable POLL cpupower -c 15 frequency-info
输出结果中 POLL 已经被禁用.
CPUidle driver: intel_idle CPUidle governor: menu analyzing CPU 15: Number of idle states: 4 Available idle states: POLL C1 C1E C6 POLL (DISABLED) : Flags/Description: CPUIDLE CORE POLL IDLE Latency: 0 Usage: 5442095 Duration: 27783830 C1: Flags/Description: MWAIT 0x00 Latency: 2 Usage: 227929586 Duration: 9066384859 C1E: Flags/Description: MWAIT 0x01 Latency: 10 Usage: 144210011 Duration: 29640193014 C6: Flags/Description: MWAIT 0x20 Latency: 133 Usage: 292763623 Duration: 3842674571060
2.2 CPUFreq (P-State)
Ubuntu
-
frequency-info
# -c/--cpu 指定cpu编号 cpupower -c 0 frequency-info
输出中提供了 CPU 的
maximum transition latency
,hardware limits
,available cpufreq governors
,current CPU frequency
analyzing CPU 0: driver: intel_pstate CPUs which run at the same hardware frequency: 0 CPUs which need to have their frequency coordinated by software: 0 maximum transition latency: Cannot determine or is not supported. hardware limits: 1000 MHz - 3.20 GHz available cpufreq governors: performance powersave current policy: frequency should be within 1000 MHz and 3.20 GHz. The governor "powersave" may decide which speed to use within this range. current CPU frequency: Unable to call hardware current CPU frequency: 2.04 GHz (asserted by call to kernel) boost state support: Supported: yes Active: yes
-
frequency-set
# 可用cpufreq-set --help查看flags # 设置最小2.0GHz频率,最大2.5GHzx频率 cpupower --cpu 15 frequency-set --min 2.0GHz --max 2.5GHz # 当前策略选择 cpupower -c 15 frequency-info
输出结果可见,
current policy
显示了我们的参数值,同时观察了其他 CPU,并无变化。analyzing CPU 15: driver: intel_pstate CPUs which run at the same hardware frequency: 15 CPUs which need to have their frequency coordinated by software: 15 maximum transition latency: Cannot determine or is not supported. hardware limits: 1000 MHz - 3.20 GHz available cpufreq governors: performance powersave current policy: frequency should be within 2.00 GHz and 2.50 GHz. The governor "performance" may decide which speed to use within this range. current CPU frequency: Unable to call hardware current CPU frequency: 2.24 GHz (asserted by call to kernel) boost state support: Supported: yes Active: yes
2.3 Workload (Utilization)
基于该工具实现了 CPU 负载生成:https://github.com/SheepHuan/cpuload
3 实验观察
设置了 3 个实验,这里我们无法设置确定的频率。在Intel(R) Xeon(R) Gold 5120 CPU
实验的。
-
设置 cpu50,利用率 15%,频率在 2.4GHz-2.5GHz;cpu52,利用率 95%,频率在 2.4GHz-2.5GHz。
图 3-1 -
设置 cpu50,利用率 15%,频率在 2.499GHz-2.5GHz;cpu52,利用率 95%,频率在 2.499GHz-2.5GHz。
图 3-2 -
设置 cpu50,利用率 15%,频率在 0.9GHz-1.0GHz;cpu52,利用率 95%,频率在 2.4GHz-2.5GHz。
图 3-3
- 图 3-1 中基本上 cpu52 的频率稳定在 2.5GHz,没有什么波动,但是 cpu50 的频率在 2.4GHz 来回波动。说明 2.4GHz 的频率来说对于利用率 15%来说太高了。
- 图 3-2 中我们进一步限制频率范围 cpu50 的波动更大了,cpu52 和之前没什么区别。
- 图 3-3 中,我们将 cpu50 的频率降低后,我们发现 cpu50 频率能够稳定在 1.0GHz 了,但是两端出现了大幅度波动,不知道是不是因为还有其他进程调用了还是有其他原因。
- 在图 3-1,2,3 中,我们发现 utilization 的数值并不稳定,这个地方还要分析下为什么,检查下负载生成的部分是不是实现的不好(TODO)。