前语
本系列文章将结合近年来不断在各种硬件(包含 CPU、芯片组、PCI Express 等各种最新总线规范以及外设)上新增的节能技能。
从 Linux® 2.6内核及整个 software stack (包含 kernel、middleware 以及各种用户态 utility)怎么增加对这些立异的节能技能的支撑这一视点,为读者介绍 Linux 操作体系近几年来在电源办理方面所获得的长足进步以及未来的开展方向。
作为本系列文章的开篇之作,首要要向咱们介绍的是 cpufreq,它是 Linux 2.6内核为了更好的支撑近年来在各款干流CPU 处理器中呈现的变频技能而新增的一个内核子体系。
Cpufreq 的由来
跟着 energy efficient computing 和 performance per watt 等概念的推行以及高档装备与电源接口ACPI(Advanced Configuration and Power Interface)规范的开展,现在市场上的干流 CPU 都供给了对变频(frequency scaling)技能的支撑。例如Intel®处理器所支撑的 Enhanced SpeedStep® 技能和 AMD® 处理器所支撑的 PowerNow! ® 技能,别的像最新的PowerPC®、ARM®、SPARC® 和 SuperH® 等处理器中也供给了相似的支撑。参考资料中列出了当时 Linux 2.6内核所支撑的具有变频技能的处理器。需求留意的是,这儿要评论的变频技能与咱们以前所熟知的超频是两个不同的概念。超频是指经过进步中心电压等手法让处理器作业在非规范频率下的行为,这往往会形成 CPU 运用寿命缩短以及体系稳定性下降等严重结果。
而变频技能是指CPU硬件自身支撑在不同的频率下运转,体系在运转过程中能够依据随时或许发生改变的体系负载状况动态在这些不同的运转频率之间进行切换,然后到达对功能和功耗做到二者统筹的意图。
尽管多个处理器出产厂家都供给了对变频技能的支撑,可是其硬件完成和运用方法必定存在着纤细乃至巨大的不同。这就使得每个处理器出产厂家都需求依照其特别的硬件完成和运用方法向内核中增加代码,然后让自己产品中的变频技能在 Linux 中得到支撑和运用。可是,这种内核开发形式所导致的结果是各个厂家的完成代码散落在 Linux 内核代码树的各个角落里,各种不同的完成之间没有任何代码是同享的,这给内核的保护以及将来增加对新的产品的支撑都带来了巨大的开支,并直接导致了 cpufreq 内核子体系的诞生。实际上,正如前文所说,创造变频技能的意图是为了能够让体系在运转过程中随时依据体系负载的改变动态调整 CPU 的运转频率。这件作业能够分为两个部分,一部分是“做什么”的问题,另一部分是“怎么做”的问题。“做什么”是指怎么依据体系负载的动态改变挑选出 CPU 适宜的运转频率,而“怎么做”便是要依照选定的运转频率在选定的时刻对 CPU 进行设置,使之真实作业在这一频率上。这也便是咱们在软件规划中经常会遇到的机制 mechanism 与战略 policy 的问题,而规划杰出的软件会在架构上确保二者是被明晰的隔脱离的并经过规范界说的接口进行通讯。
Cpufreq 的规划和运用
为了处理前文所说到的问题,一个新的内核子体系—— cpufreq 应运而生了。Cpufreq 为在Linux 内核中更好的支撑不同 CPU 的变频技能供给了一个一致的规划结构,其软件结构如图 1 所示。
图 1. Cpufreq 的软件结构
如图 1 所示,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/
这其间的一切可读文件都能够运用 cat 指令进行读操作,别的一切可写文件都能够运用 echo 指令进行写操作。其间cpuinfo_max_freq 和 cpuinfo_min_freq 别离给出了CPU 硬件所支撑的最高运转频率及最低运转频率, cpuinfo_cur_freq 则会从 CPU 硬件寄存器中读取 CPU 当时所在的运转频率。尽管 CPU 硬件支撑多种不同的运转频率,可是在有些场合下用户能够只挑选运用其间的一个子集,这种操控是经过scaling_max_freq 和 scaling_min_freq 进行的。Governor在挑选适宜的运转频率时只会在 scaling_max_freq 和scaling_min_freq 所确认的频率范围内进行挑选,这也便是scaling_available_frequencies 所显现的内容。与cpuinfo_cur_freq 不同, scaling_cur_freq 回来的是cpufreq 模块缓存的 CPU 当时运转频率,而不会对 CPU 硬件寄存器进行检查。 scaling_available_governors 会告知用户当时有哪些 governors 可供用户运用,而 scaling_driver 则会显现该 CPU 所运用的变频驱动程序。 Stats 目录下给出了对 CPU 各种运转频率的运用计算状况,例如 CPU 在各种频率下的运转时刻以及在各种频率之间的变频次数。 Ondemand 目录则与 ondemand governor 相关,在后文会进行相应的介绍。
经过以上的介绍,咱们对怎么运用 cpufreq 经过 sysfs 供给的用户接口已经有了大致的了解,可是关于绝大部分用户而言,逐个操作这些文件既吃力又耗时。因而 Dominik 等人开发了cpufrequtils 工具包[2],为用户供给了愈加简洁的对内核cpufreq 子体系的操作接口。经过 cpufreq-info 的输出,读者能够很清楚的看到刚刚在上面介绍过的/sys/devices/system/cpu/cpuX/cpufreq/ 目录下各个文件的内容。
$ cpufreq-info
cpufrequtils 002: cpufreq-info (C) Dominik Brodowski
2004-2006
Report errors and bugs to linux@brodo.de, please.
analyzing CPU 0:
driver: acpi-cpufreq
CPUs which need to switch frequency at the same time:
0 1
hardware limits: 1000 MHz – 1.67 GHz
available frequency steps: 1.67 GHz, 1.33 GHz, 1000
MHz
available cpufreq governors: userspace, conservative,
ondemand, powersave, performance
current policy: frequency should be within 1000 MHz
and 1.67 GHz.
The governor “ondemand” may decide which
speed to use
within this range.
current CPU frequency is 1000 MHz.
analyzing CPU 1:
driver: acpi-cpufreq
CPUs which need to switch frequency at the same time:
0 1
hardware limits: 1000 MHz – 1.67 GHz
available frequency steps: 1.67 GHz, 1.33 GHz, 1000
MHz
available cpufreq governors: userspace, conservative,
ondemand, powersave, performance
current policy: frequency should be within 1000 MHz
and 1.67 GHz.
The governor “ondemand” may decide which
speed to use
within this range.
current CPU frequency is 1000 MHz.
Ondemand governor 的由来及其完成刚刚咱们在 cpufreq-info 的输出中能够看到 cpufreq 子体系总共供给了五种 governors 供用户挑选运用,它们别离是 userspace,conservative,ondemand,powersave 和performance。在最新的内核中假如用户不进行额定设置的话,ondemand 会被作为默许的 governor 运用。为了了解是什么原因形成了这种现状,咱们在这儿带领读者回忆一下 cpufreq 子体系中的governor在内核中的开发前史。
Cpufreq 作为一个子体系最早被加入到 Linux 内核中时只装备了三个governors ,别离是performance、powersave 和userspace。当用户挑选运用 performance governor 时,CPU会固定作业在其支撑的最高运转频率上;当用户挑选运用powersave g