C-states、C-mode简介
为了在CPU空闲时节约能源,可以让CPU进入低功耗模式。C-state是intel CPU处于空闲时的一种状态,CPU有几种电源模式,它们统称为“c状态”或"c模式"。CPU的每个状态都使用不同的电量,并且对应用程序性能的影响也不同。
每当CPU内核处于空闲状态时,内置的节能逻辑就会启动,并尝试将内核从当前的C状态转换为更高的C状态,从而关闭各种处理器组件以节省功耗。应用程序尝试在一个CPU来执行某些任务时,相应的CPU必须从其“更深的睡眠状态”返回到“运行状态”,这需要更多时间来唤醒计算机。
CPU过渡到的各种C模式称为C-state。它们通常从C0开始,但C0比较特殊,它正常的CPU工作模式,即CPU已100%的开启。随着C-state级别的增加,CPU睡眠模式会更深,即更多的电路和信号将被关闭,并且CPU需要更多的时间才能返回到C0模式(即唤醒)。每种模式也有一个名称,其中每个c-state具有不同的省电策略,有些c级别还有不同的子模式。如下图
如何禁用处理器睡眠状态
方法1:通过修改grub文件中内核命令行参数processor.max_cstate=0、intel_idle.max_cstate=0进行引导,让系统不进入深度的C状态。
参数说明:
intel_idle.max_cstate=0:在intel平台上,模式会使用intel cpuidle drviver,intel_idle.max_cstate=0 意味着禁用intel cpuidle driver,让其退化使用acpi driver。
processor.max_cstate=0:描述acpi driver中cpu cstate的最大级别,但是实际max_cstate=0并不能真的让CPU保持在C0态,只能让CPU保持在C1状态
方法2:在BIOS里面进行设置,关闭c-state
CPU允许的最大C-state
intel CPU一般会有多个CPU c-state,但实际也要根据内核启动参数中的max_cstate设定值,具体来说不同型号的处理器所允许的最大c状态会有所不同。查看方法
cat /sys/module/intel_idle/parameters/max_cstate
如何检查和监视Linux中每个CPU和内核的CPU c状态使用情况?
intel平台可以使用turbostat工具,该工具可以查所有可用CPU核心的c-state使用量及占用百分比。
POLL idle状态
前面通过设置内核启动参数processor.max_cstate=0、intel_idle.max_cstate=0,都不能让CPU完全不进入C-state,因为cpu idle enter代码进入了C1状态,cmdline添加idle=poll参数可以让CPU完全处于C0状态,当CPU空闲时其实是执行busy-loop。
POLL idle状态不是真正的空闲状态,它不节省任何功率。取而代之的是,执行busy-waiting。如果足够了解你的应用程序,对延迟很敏感,让内核知道必须尽快处理工作,因为进入任何实际的硬件空闲状态可能会导致轻微的性能损失,则可以使用此状态。
X86体系结构平台上存在两种不同的cpuidle驱动程序:
“acpi_idle" cpuidle驱动程序,acpi_idle cpuidle驱动程序从ACPI BIOS表(从最新平台上的_CST ACPI函数或从较旧平台上的FADT BIOS表)检索可用的睡眠状态(C状态)。不会从ACPI表中检索C1状态。如果进入C1状态,内核将调用hlt指令(或Intel上的mwait)。
“intel_idle” cpuidle驱动程序 在内核2.6.36中引入了intel_idle驱动程序。它仅服务于最近的Intel CPU。在较旧的Intel CPU上,仍使用acpi_idle驱动程序(如果BIOS提供C状态ACPI表)。intel_idle驱动程序知道处理器的睡眠状态功能,并忽略ACPI BIOS导出的处理器睡眠状态表。
如何查看当前加载的驱动程序
intel_idle驱动程序是支持现代Intel处理器的CPU idle驱动程序。
intel_idle驱动程序为内核提供目标驻留时间和每个受支持的英特尔处理器的退出延迟时间。
查看方法
cat /sys/devices/system/cpu/cpuidle/current_driver