最近在进行网络性能测试的时候进程会遇到系统C-state,P-state以及turbo的相关设置,虽然知道都是和CPU功耗有关,但具体有什么联系以及对当前进程的影响并不是很清楚,于是查了一下相关资料做一个总结记录。
首先C-state和P-state是完全不同的概念和维度,官方解释是“C-states are idle states and P-states are operational states”。,此外C-States(CPU Power states)指CPU电源状态,而P-States(CPU Performance states)则指CPU性能状态。下面我们逐个分析一下。
C-state
C-state有C0,C1...Cn多种模式,但只有C0是正常工作模式(active),其他方式都是idle状态,只是idle的程度不同,C后的数越高,CPU睡眠得越深,CPU的功耗被降低得越多,同时需要更多的时间回到C0模式。 那么是什么决定了idle的程度或者说睡眠的程度呢?答案是stop CPU功能的多少,CPU的功能被阉割的越多就越省电,当然恢复正常状态就需要越长时间。每一个模式都有一个对应的名字,有的模式还有子模式,子模式又具有不同功耗和唤醒时间。在下表所列的模式中,C1到C3通过切断CPU内部的时钟,C4到C6模式通过降低CPU的电压。"Enhanced"模式两种方式都采用。
CPU在C0状态时会执行指令,但是即使在C0状态下OSPM仍然可以通过调整CPU的工作电压和频率的方式,以此降低整个平台的功耗。P-state 在Intel平台上通常指的是EIST(Enhanced Intel SpeedStep Technology),EIST允许多个核动态的切换电压和频率,动态的调整系统的功耗。OSPM通过WRMSR指令写IA32_PERF_CTL MSR的方式调整CPU电压和<u style="overflow-wrap: break-word;">工作频率</u>。
允许多个核动态的切换电压和频率,动态的调整系统的功耗。通常 P0 指的就是处理器以最高频率、最高运算量的状态运作,接下来 P1、P2、P3……就依照运作效能的多少、省电性由少至多依序排下去。 Intel 的 Turbo Boost 技术就是当系统工作要求处理器运作在 P0 状态时,收集有关目前处理器耗电量、启动核心数量、核心电源状态、处理器温度等信息,来决定P0的运作频率多少。
可以通过修改grub启动文件开启P-state,一般情况下我们也会通过限制max_cstate来限制C-state的最大睡眠深度。
修改/etc/default/grub配置行GRUB_CMDLINE_LINUX添加intel_idle.max_cstate=1 intel_pstate=enable processor.max_cstate=1
grub2-mkconfig -o /boot/grub2/grub.cfg
Turbo P-states
P-state可以和turbo(睿频)相结合,如果/sys/devices/system/cpu/intel_pstate/no_turbo被设置为0,说明使能了turbo P-state。
P-state支持的所有频率范围可以分为两个部分,有一个分界的阈值turbo threshold,超过这个阈值的P-state称之为turbo P-states。turbo P-states有一个问题是无法指定CPU具体是在哪个turbo P-states,这个会随着CPU功耗的增加减少动态调节,而在turbo threshold之下的P-state是可以指定的。关于turbo详细在Turbo Boost中讲解。
Turbo Boost
Intel Turbo Boost是Intel在系列处理器实现的技术,通过动态控制处理器的时钟率来激活处理器运行在超过基础操作主频。
支持不同Turbo Boost版本技术的处理器分为:
Turbo Boost 1.0: Nehalem
Turbo Boost 2.0: Sandby Bridge
Turbo Boost Max 3.0: Ivy Bridge, Haswell, Broadwell, Skylake, Broadwell-E
Turo Boost是在操作系统请求处理器的最高性能状态(highest performance state, pstate)时候激活。
处理器性能状态是通过高级配置和电源接口(Advanced Configuration and Power Interface, ACPI)规范来定义的,这是被所有主流操作系统所支持的开放标准。在Turbo Boost背后的设计概念也被称为"动态超频"。
时钟主频是由处理器电压,电流和热量所限制的,同时也受到当前CPU核心数量和激活核心的最高主频限制。当处理器上负载调用更快性能,并且此时处理器还没有达到上限,则处理器时钟将增加操作频率以满足需求。频率增长,在Nehalem处理器是133MHz,而在Sand Bridge, Ivy Bridge,Haswell和Skylake处理器是100MHz。
Intel Turbo Boost监控处理器当期使用情况,以及处理器是否接近最大热量设计功率(thermal design power, TDP)。这个TDP是处理器支持的最大功率。
Turbo Boost是动态功能,Turbo Boost以133MHz步长增长,直到达到允许的最大Turbo Boost(和处理器型号相关)或者最大TDP。不过,Intel仍然建议处理器工作在基础时钟速度(base clock speed),因为Intel不承诺处理器任何时候都能够达到最大Turbo Boost speed。
Turbo Boost允许一个或多个CPU核心运行在更高的P-states(turbo P-state),这个最大P-state需要考虑以下因素:
激活的核心数量( C0状态)
评估当前处理器消耗(Imax)
评估处理器电能消耗(TDP - Thermal Design Power)
处理器稳定
所以,内核启动参数需要激活****P-state****驱动后才能使用****Turbo Boost****功能。
Turbo Boot Max 3.0
Intel Turbo Boost Max Technology 3.0 使用一个和CPU中存储信息相连的驱动。它标识并直接工作在最快的芯片内核上。驱动也允许通过白名单自定义配置以便让用户设置应用程序的优先级。这个驱动必须在系统中存在和正确配置,否则操作系统就不能有效路由工作负载到目标处理器核心。
要使用Intel Turbo Boost Max Technology 3.0需要同时满足条件:
CPU处理器支持 (需要检查Intel CPU功能)
操作系统支持
驱动和相应的应用软件
X99或X299主板并使用激活BIOS/firmware支持
和Intel Turbo Boost Technology 2.0不同的是,3.0版本允许单核心更高的主频。
Intel Turbo Boost Max技术的软件用户接口和驱动允许用户优先将负载(应用)直接调度到最快的CPU核心上。
支持Core List是处理器核心的顺序列表,最高性能的core位于最高。更改列表顺序可能会重新以对应性能来表述处理器核心。在操作系统的core序号体系和处理器序号体系相关。例如,Core 0对应逻辑处理器0和1,Core 1对应逻辑处理器2和3。
当每个CPU核心最大主频超过时钟 - Overclocking Enabled显示了Core List的优先级。
Turbo Boost Max技术支持设置应用程序可以使用的CPU性能的百分比(阀值),以及评估时间间隔: 默认的评估时间间隔单位是100ms,默认值是10,也就是10x100ms=1s,即每秒评估一次;CPU使用阀值默认是90%,调整这个阀值会降低程序消耗的系统性能。
cpufreq子系统
cpufreq 为在Linux 内核中更好的支持不同 CPU 的变频技术提供了一个统一的设计框架,其软件结构如下:
cpufreq 在设计上主要分为以下三个模块:
cpufreq 模块(cpufreq module)对如何在底层控制各种不同 CPU 所支持的变频技术以及如何在上层根据系统负载动态选择合适的运行频率进行了封装和抽象,并在二者之间定义了清晰的接口,从而在设计上完成了前文所提到的对 mechanism 与 policy 的分离。
在 cpufreq 模块的底层,各个 CPU 生产厂商只需根据其变频技术的硬件实现和使用方法提供与其 CPU 相关的变频驱动程序(CPU-specific drivers),例如 Intel 需要提供支持 Enhanced SpeedStep 技术的 CPU 驱动程序,而 AMD 则需要提供支持 PowerNow! 技术的 CPU 驱动程序。
在 cpufreq 模块的上层,governor 作为选择合适的目标运行频率的决策者,根据一定的标准在适当的时刻选择出 CPU 适合的运行频率,并通过 cpufreq 模块定义的接口操作底层与 CPU 相关的变频驱动程序,将 CPU 设置运行在选定的运行频率上。目前最新的 Linux 内核中提供了 performance 、powersave 、userspace、conservative 和 ondemand 五种 governors 供用户选择使用,它们在选择 CPU 合适的运行频率时使用的是各自不同的标准并分别适用于不同的应用场景。用户在同一时间只能选择其中一个 governor 使用,但是可以在系统运行过程中根据应用需求的变化而切换使用另一个 governor 。
这种设计带来的好处是使得 governor 和 CPU 相关的变频驱动程序的开发可以相互独立进行,并在最大限度上实现代码重用,内核开发人员在编写和试验新的 governor 时不会再陷入到某款特定 CPU 的变频技术的硬件实现细节中去,而 CPU 生产厂商在向 Linux 内核中添加支持其特定的 CPU 变频技术的代码时只需提供一个相对来说简单了很多的驱动程序,而不必考虑在各种不同的应用场景中如何选择合适的运行频率这些复杂的问题。
内核中的 cpufreq 子系统通过 sysfs 文件系统向上层应用提供了用户接口,对于系统中的每一个 CPU 而言,其 cpufreq 的 sysfs 用户接口位于 /sys/devices/system/cpu/cpuX/cpufreq/ 目录下,其中 X 代表 processor id ,与 /proc/cpuinfo 中的信息相对应。以 cpu0 为例,用户一般会在该目录下观察到以下文件:
|
$ ls -F /sys/devices/system/cpu/cpu0/cpufreq/
affected_cpus
cpuinfo_cur_freq
cpuinfo_max_freq
cpuinfo_min_freq
ondemand/
scaling_available_frequencies
scaling_available_governors
scaling_cur_freq
scaling_driver
scaling_governor
scaling_max_freq
scaling_min_freq
stats/
|
linux频率管理相关工具
cpupower monitor -l可以列出所有可以监控的模块,如:
cpupower frequency-info可以检查处理器主频:
#cpupower frequency-info
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: 0.97 ms.*
hardware limits: 1000 MHz - 3.10 GHz*
available cpufreq governors: performance, powersave*
current policy: frequency should be within 1000 MHz and 3.10 GHz.*
The governor "powersave" may decide which speed to use*
within this range.*
current CPU frequency is 2.70 GHz (asserted by call to hardware).*
boost state support:*
Supported: yes*
Active: yes*
其中hardware limits表示CPU支持的频率范围;
current policy表示当前配置下CPU的支持的频率波动范围;
注意:使用cpupower frequency-info****显示的当前cpu 0****主频是一个约数,不精确且有延迟。最好采用 ****cpupower monitor -m Mperf ****检查能够获取精确的CPU****主频,且即使没有使用intel_pstate驱动也能够准确获取频率。
检查处理器主频cpupower monitor -m Mperf
$sudo cpupower monitor -m Mperf
|Mperf*
PKG |CORE|CPU | C0 | Cx | Freq
0| 0| 0| 7.85| 92.15| 2820*
0| 0| 32| 0.38| 99.62| 2825*
0| 1| 1| 42.75| 57.25| 2891*
0| 1| 33| 6.98| 93.02| 2890*
...
可以看到Cx显示的就是处理器idle的状态
cpupower idle-info命令列出支持的C-State
cpupower idle-info
CPUidle driver: intel_idle
CPUidle governor: menu
Analyzing CPU 0:
Number of idle states: 2
Available idle states: POLL C1-SKX
POLL:
Flags/Description: CPUIDLE CORE POLL IDLE
Latency: 0
Usage: 2667
Duration: 296902700
C1-SKX:
Flags/Description: MWAIT 0x00
Latency: 2
Usage: 776606
Duration: 14056122480
以上信息表示当前系统支持POLL,C1-SKX两种idle C-state,并且都没有disable。注意:系统必须加载了intel_idle驱动之后才能列出支持的C-state。
intel_pstate/no_turbo
可以在intel_pstate驱动中关闭turob(设置intel_pstate/no_turbo值为1)
echo 1|sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo
要检查是否启用和停止Turbo,可以通过:
- cat /sys/devices/system/cpu/intel_pstate/no_turbo* 来检查
Turbo Boost也可以在运行时通过禁止intel_pstate驱动来关闭:
echo off |sudo tee /sys/devices/system/cpu/intel_pstate/status
注意:这里禁用intel_pstate之后,处理器主频会跌到物理主频的最小值,此时需要通过MSR寄存器199H来静态设置目标性能状态值(Target performance State Value)
也可以激活intel_pstate驱动:
echo active |sudo tee /sys/devices/system/cpu/intel_pstate/status
注意:这个intel_pstate/status入口必须在激活Turbo Boost之后才会存在
cpupower frequency-info读取CPU主频
注意,默认没有指定cpu参数则读取cpu 0主频。要读取指定cpu的主频,需要使用-c参数,例如,读取cpu 31的主频
cpupower -c 31 frequency-info
不过,cpupower frequency-info 是通过intel_pstate驱动来获取信息的,所以如果使用 echo off |sudo tee /sys/devices/system/cpu/intel_pstate/status 禁用了intel_pstate驱动,则该指令失效。
可以通过cpupower monitor指令来获取CPU主频,该指令是直接读取MSR 198H 来直接获取CPU主频信息,所以即使禁用了intel_pstate驱动也可以获得准确的数据。
cpupower monitor
使用turbostat读取主频
turbostat默认10秒刷新一次,可以使用-i 1可以1秒刷新一次。
Avg_MHz是平均主频,基于APERF
Busy%表示处理器繁忙百分比
Bzy_MHz是实际的busy frequency,基于MPERF
TSC_MHz是固定主频,TSC基于
APERF (average) and MPERF (maximum) 是MSR寄存器可以提供当前CPU主频信息。
通过cpupower frequency-set设置cpu的频率
可以通过cpupower frequency-set --min/--max $freq 来设置当前系统的cpu频率范围。
查看设置系统的governor
同样通过cpupower frequency-info可以查看当前系统支持的governor,已经在使用的governor。
#cpupower frequency-info
analyzing CPU 0:
……*
available cpufreq governors: performance, powersave*
current policy: frequency should be within 1000 MHz and 3.10 GHz.*
The governor "powersave" may decide which speed to use*
within this range.*
如上,表示当前系统支持performance, powersave两种governor,而当前正在使用的是powersave。
可以通过*cpupower frequency-set --governor $governor*来设置当前系统使用的governor。