# CPU Frequency Scaling (简体中文)

翻译状态： 本文是英文页面 CPU_Frequency_Scaling 的翻译，最后翻译时间：2013-04-04，点击这里可以查看翻译后英文页面的改动。

相关文章

- Laptop Mode Tools
- pm-utils
- PHC

CPUfreq 引用了内核架构中的CPU频率调整部分相关功能。这项技术使得操作系统能够提高或降低CPU速度来达到省电目的。CPU频率可以根据系统负荷自动调整，或响应ACPI事件而调整，或通过用户空间程序手工调整。

从内核3.4开始，必要的模块都会自动加载，而且推荐的调速器ondemand governor默认启动。但是，用户空间程序，例如cpupower，acpid，laptop-mode-tools，或你的桌面系统对应的图形化工具，在进行高级特性配置时可能仍然需要被用到。

## 用户空间工具（cpupower）

cpupower是一组设计为辅助CPU frequency scaling的一组用户空间工具。为使用频率调整的功能，这个软件包并不是必须的，但强烈建议安装，因为它提供了方便的命令行工具和在启动时改变调速器的服务。 cpupower的配置文件位于`/etc/default/cpupower`。这个配置文件被bash脚本读取，该脚本位于`/usr/lib/systemd/scripts/cpupower`，它又由`systemd`通过`cpupower.service`激活。为使用systemd在启动时启用cpupower，运行：

    # systemctl enable cpupower.service

gnome-shell前端工具可以在以下地址找到：CPU Freq.

### CPU频率驱动

注意: 从内核3.4以后本地CPU模块会自动加载。

cpupower需要一些模块（见下表）来了解本地CPU的限制参数。如果想查看所有可用模块的完整列表，运行：

    $ ls /lib/modules/$(uname -r)/kernel/drivers/cpufreq/

Tip: 如需在启动时加载模块，运行：

    # echo <module> >/etc/modules-lo-ad.d/<module>.conf

注意: 试图加载错误的模块会导致错误“没有此设备”。

加载正确的模块：

    # modprobe <module>

模块 | 描述
--- | ---
acpi-cpufreq | 支持ACPI Processor Performance States的CPUFreq驱动。该驱动也支持Intel Enhanced SpeedStep（之前由已过期的模块speedstep-centrino支持）。
speedstep-lib | 支持拥有speedstep功能的Intel处理器（通常是atom和奔腾3代或更老的处理器）CPUFreq驱动。
speedstep-smi | 支持部分移动Intel奔腾III (Coppermine)的CPUFreq驱动。该驱动支持所有具备Intel 440BX/ZX/MX南桥芯片系统中的移动Intel奔腾III-M (Tualatin) 。
powernow-k8 | 支持K8/K10 Athlon64/Opteron/Phenom处理器的CPUFreq驱动。从linux 3.7开始进入淘汰阶段，使用acpi-cpufreq替代。
powernow-k7 | 支持移动AMD K7处理器的CPUFreq驱动。
cpufreq-nforce2 | 支持nForce2平台下外频调整的CPUFreq驱动（AMD K7, Socket A）
pcc-cpufreq | 支持HP和微软提出的“处理器时钟频率控制”接口，这在一些Proliant服务器上很有用。
p4_clockmod | 支持Intel奔腾4 / 至强 / 赛扬 处理器的CPUFreq驱动。生效时会通过skipping clocks技术降低CPU发热量。 你可能更希望使用Speedstep驱动代替它。

一旦加载了正确的cpufreq驱动，CPU的详细信息可以通过以下命令来查看：

    $ cpupower frequency-info

### 调整调速器

可以把调速器（见下表）想象成预设的CPU电源方案。在同一时刻只会有一个会调速器被激活。

注意: 内核默认加载`on_demand`。

模块 | 描述
--- | ---
cpufreq_ondemand | 在达到95%CPU负载时动态在可用范围内调整。
cpufreq_performance | CPU运行在最大频率。
cpufreq_conservative | 在达到75%CPU负载时动态在可用范围内调整。
cpufreq_powersave | CPU运行在最小频率。
cpufreq_userspace | CPU运行在用户指定频率。

Tip: 想要实时监控CPU频率，运行：

    $ watch grep \"cpu MHz\" /proc/cpuinfo

#### 使用cpupower

要加载和激活一个特定的调速器，应该运行：

    # cpupower frequency-set -g <governor_without cpufreq_>

#### 不使用cpupower

Tip: 要在启动时加载调速器，运行：

    # echo <module> > /etc/modules-load.d/<module>

要加载一个特定的调速器，应该运行：

    # modprobe <governor>

### 调整调速器（使用cpupower）

Tip: 在`/etc/default/cpupower`文件尾加上以下命令行。<percent>是CPU负载百分比；<governor>是cpupower调速器。

设置跳到更高频率的阈值：

    # echo -n <percent> > /sys/devices/system/cpu/cpufreq/<governor>/up_threshold

设置跳到更低频率的阈值：

    # echo -n <percent> > /sys/devices/system/cpu/cpufreq/<governor>/down_threshold

#### 采样率

采样率决定调速器多久进行一次检查并调整CPU频率。 设置`sampling_down_factor`大于1将通过降低负载评估的消耗，并将CPU保持在最高运行频率而提高性能。这个可调参数对低CPU频率/负载没有效果。

要获取这个值 (default = 1)，运行：

    $ cat /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor

要设置这个值，运行：

    # echo -n <value> > /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor

### 设置最大和最小频率

注意: 调速器，最大频率，最小频率可以在`/etc/default/cpupower`中设置。如果只想为一个CPU内核调整：`-c <core #>`. <clock_freq> 是一个带单位的CPU频率：GHz，MHz

设置最大频率：

    # cpupower frequency-set -u <clock_freq>

设置最小频率：

    # cpupower frequency-set -d <clock_freq>

设置为指定频率：

    # cpupower frequency-set -f <clock_freq>

## 与ACPI事件交互

用户可以把调速器配置为基于不同的ACPI事件自动切换的形式。例如接入外接电源，或是合上屏幕时。以下是一个简明的例子，但可能有必须通读一遍文章acpid.

事件是在`/etc/acpi/handler.sh`中定义的。如果acpid软件包已经安装，这个文件应该已经存在并且设置为可执行。例如，当外接电源拔除时将调速器从`performance`改为`conservative`，而当电源再次接入时将它改回来：

    /etc/acpi/handler.sh

    [...]

     ac_adapter)
         case "$2" in
             AC*)
                 case "$4" in
                     00000000)
                         echo "conservative" >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
                         echo -n $minspeed >$setspeed
                         #/etc/laptop-mode/laptop-mode start
                     ;;
                     00000001)
                         echo "performance" >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
                         echo -n $maxspeed >$setspeed
                         #/etc/laptop-mode/laptop-mode stop
                     ;;
                 esac
             ;;
             *) logger "ACPI action undefined: $2" ;;
         esac
     ;;

    [...]

## GNOME下的授权

注意: systemd引入了logind来处理consolekit和policykit行为。以下代码不再工作。

GNOME_(简体中文)有一个不错的小工具来在线修改调速器。如果想在不需要root密码的情况下就能使用它，只需要建立一个文件`/var/lib/polkit-1/localauthority/50-local.d/org.gnome.cpufreqselector.pkla`然后录入以下内容：

    [org.gnome.cpufreqselector]
    Identity=unix-user:USER
    Action=org.gnome.cpufreqselector
    ResultAny=no
    ResultInactive=no
    ResultActive=yes

其中`USER`替换为期望的用户名。

AUR中的软件包desktop-privileges包含一个类似的`.pkla`文件为所有`power` 用户组中的用户授权修改调速器。

## Laptop Mode Tools

如果你已经或将要使用Laptop Mode Tools (简体中文)来管理所有的省电方案，那你可能也想让它来管理CPU频率调整。为达到这个目的，你只要把合适的频率驱动插入`/etc/modules.d/`目录（查看上文#CPU频率驱动章节以得到更多信息）。然后查阅`/etc/laptop-mode/conf.d/cpufreq.conf`文件以定义调速器，频率和切换规则。你不需要加载其他模块和守护进程，或为ACPI事件配置其他调速器。请参考Laptop Mode Tools (简体中文)以获得更多详细内容。

## 疑难解答

- 一些应用程序，如ntop，对自动频率调整不能很好地响应。在ntop的案例中它可能导致分段错误和大量信息丢失，因为在大量网络数据包突然到达被监控的网络接口时，`on-demand`调速器不能迅速反应，以致当前处理速度满足不了处理这些数据包所需的速度。

- 一些CPU在默认的`on-demand`调速器配置下可能受到比较严重的性能损失（例如flash视频不能平滑地播放，或窗口动画停顿）。为了解决这些问题，完全禁用掉频率调整不如采取更积极的措施——降低每个CPU的up_threshold sysctl变量值。阅读#修改on-demand调速器的阈值章节以获得更多信息。

- 有时on-demand调速器可能达不到最高频率而只能达到次级频率。这个问题可以通过把max_freq值设置得稍微高于最大频率的方式来解决。例如，如果CPU的频率范围是2.00 GHz到3.00 GHz，把max_freq设置为3.01 GHz就是一个不错的主意。

- ALSA驱动和有些声音芯片配合工作时，可能导致在调速器改变频率时声音跳跃。改回non-changing调速器应该能够解决这个问题。

### BIOS频率限制

一些CPU/BIOS配置可能导致达不到最高频率或根本无法调高频率。这很可能是因为BIOS告诉操作系统限制频率，结果在`/sys/devices/system/cpu/cpu0/cpufreq/bios_limit`中设置了一个过低的值。

这种情况下需要在BIOS设置中修改指定的配置（频率，发热管理等）。这通常是由于有问题的/过旧的BIOS导致，也可能BIOS有特别的原因要求必须这样。

可能的原因有（假设你的机器是一台笔记本）电池被移除（或快要完全损坏），所以你只能用外接电源。这种情况下如果电源适配器提供的电能太弱，就会满足不了整个系统在峰值所需的电能，而且又没有电池辅助供电，就可能导致数据丢失，数据损坏或最坏的情况下损坏硬件！

不是所有的BIOS都会在这种情况下限制CPU频率，但如IBM/联想 Thinkpad就会。参考thinkwiki以获取更多信息thinkpad related info on this topic.

如果你检查后发现并没有不正确的BIOS设置，而且你也十分清楚自己在做什么以及可能导致的结果，你还可以选择让内核忽略BIOS限制。

警告: 请确保你读了并且完全明白上面一节内容。CPU频率限制是你BIOS的一个安全特性，通常情况下你不应该越过它。

一个特殊的参数需要传递给处理器模块。

临时尝试这办法时可以修改`/sys/module/processor/parameters/ignore_ppc`值从`0`到`1`。

要固化这个修改请参考Kernel modules或继续阅读本文。 添加`processor.ignore_ppc=1`到内核启动参数或创建

    /etc/modprobe.d/ignore_ppc.conf

    # 如果你的机器受到错误的BIOS频率限制，这应该会有帮助
    options processor ignore_ppc=1

Categories:

- Power management (简体中文)
- CPU (简体中文)