Linux cpufreq 机制
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 变频技术的代码时只需提供一个相对来说简单了很多的驱动程序,而不必考虑在各种不同的应用场景中如何选择合适的运行频率这些复杂的问题。