答案1
CPU frequency and voltage scaling code in the Linux(TM) kernel
L i n u x C P U F r e q
C P U F r e q G o v e r n o r s
- information for users and developers -
Dominik Brodowski <[email protected]>
some additions and corrections by Nico Golde <[email protected]>
Rafael J. Wysocki <[email protected]>
Viresh Kumar <[email protected]>
时钟缩放允许您动态更改 CPU 的时钟速度。这是一种节省电池电量的好方法,因为时钟速度越低,CPU 消耗的电量就越少。
内容:
什么是 CPUFreq 调节器?
Linux 内核中的控制器 2.1 性能 2.2 省电 2.3 用户空间 2.4 按需 2.5 保守 2.6 Schedutil
CPUfreq 核心中的调节器接口
参考
什么是 CPUFreq 调节器? ===============================
大多数 cpufreq 驱动程序(intel_pstate 和 longrun 除外)甚至大多数 cpu 频率缩放算法仅允许将 CPU 频率设置为预定义的固定值。为了提供动态频率缩放,cpufreq 核心必须能够告诉这些驱动程序“目标频率”。因此,这些特定的驱动程序将被转换为提供“->target/target_index/fast_switch()”调用,而不是“->setpolicy()”调用。但对于 set_policy 驱动程序,一切都保持不变。
如何决定应使用 CPUfreq 策略中的哪个频率?这可以通过使用“cpufreq 调节器”来完成。
基本上,它是以下流程图:
CPU 可设置为独立切换 | CPU 只能在特定“限制”内设置为特定频率
"CPUfreq policy"
consists of frequency limits (policy->{min,max})
and CPUfreq governor to be used
/ \
/ \
/ the cpufreq governor decides
/ (dynamically or statically)
/ what target_freq to set within
/ the limits of policy->{min,max}
/ \
/ \
Using the ->setpolicy call, Using the ->target/target_index/fast_switch call,
the limits and the the frequency closest
"policy" is set. to target_freq is set.
It is assured that it
is within policy->{min,max}
- Linux 内核中的管理器 ==================================
2.1 性能
CPUfreq 调节器“性能”将 CPU 静态设置为 scaling_min_freq 和 scaling_max_freq 边界内的最高频率。
2.2 省电
CPUfreq 调节器“powersave”将 CPU 静态设置为 scaling_min_freq 和 scaling_max_freq 边界内的最低频率。
2.3 用户空间
CPUfreq 调节器“用户空间”允许用户或以 UID“root”运行的任何用户空间程序通过在 CPU 设备目录中提供 sysfs 文件“scaling_setspeed”将 CPU 设置为特定频率。
2.4 按需
CPUfreq 调控器“ondemand”根据当前系统负载设置 CPU 频率。负载估计由调度程序通过 update_util_data->func 钩子触发;触发后,cpufreq 会检查上一周期的 CPU 使用率统计数据,调控器会据此设置 CPU。CPU 必须具有非常快速切换频率的能力。
Sysfs 文件:
采样率:
以 uS(10^-6 秒)为单位,这是您希望内核查看 CPU 使用率并决定如何处理频率的频率。通常将其设置为大约“10000”或更大的值。它的默认值是(cmp. with users-guide.txt):transition_latency
-
- 请注意,转换延迟以 ns 为单位,而采样率以 us 为单位,因此默认情况下您将获得相同的 sysfs 值。采样率应始终根据转换延迟进行调整,以将采样率设置为 bash 中转换延迟的 750 倍(如前所述,默认值为 1000),请执行以下操作:
$ echo `$(($(cat cpuinfo_transition_latency) * 750 / 1000)) > ondemand/sampling_rate
-
最小采样率:
采样率受硬件转换延迟限制:transition_latency * 100
或者受到内核限制:
- 如果设置了CONFIG_NO_HZ_COMMON,则限制固定为10ms。
- 如果未设置 CONFIG_NO_HZ_COMMON 或使用 nohz=off 启动参数,则限制取决于 CONFIG_HZ 选项:HZ=1000:min=20000us(20ms)HZ=250:min=80000us(80ms)HZ=100:min=200000us(200ms)
显示内核和硬件延迟限制的最高值并用作最小采样率。
上限阈值:
这定义了“sampling_rate”采样之间的平均 CPU 使用率,以便内核决定是否应增加频率。例如,当它设置为默认值“95”时,这意味着在检查间隔之间,CPU 的平均使用率需要超过 95%,然后才能决定是否需要增加 CPU 频率。
忽略_nice_load:
此参数的值为“0”或“1”。设置为“0”(默认值)时,所有进程都计入“CPU 利用率”值。设置为“1”时,以“nice”值运行的进程将不计入(因此将被忽略)总体使用率计算中。如果您在笔记本电脑上运行 CPU 密集型计算,而您不关心完成它需要多长时间,那么这很有用,因为您可以对其进行“nice”并阻止它参与决定是否增加 CPU 频率的过程。
采样下降因子:
此参数控制内核在以最高速度运行时决定何时降低频率的速率。当设置为 1(默认值)时,无论当前时钟速度如何,都会以相同的间隔做出重新评估负载的决定。但是,当设置为大于 1(例如 100)时,当 CPU 由于高负载而处于最高速度时,它将充当重新评估负载的调度间隔的乘数。这通过减少负载评估的开销并帮助 CPU 在真正繁忙时保持最高速度(而不是速度来回变化)来提高性能。此可调参数对较低速度/较低 CPU 负载下的行为没有影响。
省电偏置:
此参数取值范围为 0 到 1000。它定义了目标频率的百分比(乘以 10)。例如,当设置为 100 -- 10% 时,当按需调节器原本以 1000 MHz 为目标时,它将以 1000 MHz -(1000 MHz 的 10%)= 900 MHz 为目标。默认情况下,此参数设置为 0(禁用)。
当加载 AMD 频率灵敏度省电偏差驱动程序 — drivers/cpufreq/amd_freq_sensitivity.c 时,此参数定义工作负载频率灵敏度阈值,在该阈值中,将选择较低的频率而不是按需调节器的原始目标。频率灵敏度是硬件报告的(在 AMD 系列 16h 处理器及以上版本上)介于 0 到 100% 之间的值,它告诉软件在频率变化时 CPU 上运行的工作负载的性能将如何变化。灵敏度为 0%(内存/IO 绑定)的工作负载在更高的核心频率下不会表现更好,而灵敏度为 100%(CPU 绑定)的工作负载在频率更高时会表现更好。加载驱动程序时,默认设置为 400 — 对于运行灵敏度值低于 40% 的工作负载的 CPU,将选择较低的频率。卸载驱动程序或写入 0 将禁用此功能。
2.5 保守派
CPUfreq 调速器“保守”,与“ondemand”调速器非常相似,根据当前使用情况设置 CPU 频率。其行为不同之处在于,它会适度地增加和减少 CPU 速度,而不是在 CPU 负载时立即跳到最大速度。此行为更适合电池供电环境。该调速器的调整方式与“ondemand”调速器相同,通过 sysfs 进行调整,但增加了:
频率步长:
这描述了 CPU 频率应以百分比步长平稳增加和减少。默认情况下,CPU 频率将以最大 CPU 频率的 5% 为单位增加。您可以将此值更改为 0 到 100 之间的任何值,其中“0”将有效地将您的 CPU 锁定在某个速度,而不管其负载如何,而“100”在理论上将使其行为与“按需”调节器相同。
下限阈值:
与“ondemand”调节器的“up_threshold”相同,但方向相反。例如,当设置为其默认值“20”时,这意味着如果 CPU 使用率需要在采样之间低于 20%,频率就会降低。
采样下降因子:
与“按需”调控器的功能类似。但在“保守”调控器中,它控制内核在任何速度下运行时决定何时降低频率的速率。频率增加的负载仍会在每个采样率下进行评估。
2.6 Schedutil
“schedutil”调控器旨在更好地与 Linux 内核调度程序集成。负载估计是通过调度程序的每实体负载跟踪 (PELT) 机制实现的,该机制还提供有关最近负载的信息 [1]。此调控器目前仅对 CFS 管理的任务执行基于负载的 DVFS。RT 和 DL 调度程序任务始终以最高频率运行。与所有其他调控器不同,代码位于 kernel/sched/ 目录下。
Sysfs 文件:
rate_limit_us:
这包含一个以微秒为单位的值。在评估负载一次后,调控器将等待 rate_limit_us 时间,然后再次重新评估负载。
有关与其他调节器的深入比较,请参阅[2]。
- CPUfreq 核心中的调节器接口 =================================================
新的调节器必须使用“cpufreq_register_governor”向 CPUfreq 核心注册。必须传递给该函数的 struct cpufreq_governor 必须包含以下值:
governor->name - 该 governor 的唯一名称。 governor->owner - governor 模块的 .THIS_MODULE(如果合适)。
加上一组挂钩到实现调节器逻辑的函数。
CPUfreq 调节器可以使用以下两个函数之一来调用 CPU 处理器驱动程序:
int cpufreq_driver_target(struct cpufreq_policy *policy,无符号整数target_freq,无符号整数关系);
int __cpufreq_driver_target(struct cpufreq_policy *policy,无符号整数target_freq,无符号整数关系);
当然,target_freq 必须在 policy->min 和 policy->max 范围内。这两个函数有什么区别?当您的调控器处于对调控器回调的调用(如 governor->start())的直接代码路径中时,policy->rwsem 仍保留在 cpufreq 核心中,无需再次锁定它(事实上,这会导致死锁)。因此,仅在这些情况下使用 __cpufreq_driver_target。在所有其他情况下(例如,当有一个每秒唤醒的“守护进程”函数时),在将命令传递给 cpufreq 驱动程序之前,使用 cpufreq_driver_target 获取 policy->rwsem。
- 参考文献 ==============
[1] 每个实体的负载跟踪:https://lwn.net/Articles/531853/ [2] CPU频率管理的改进:https://lwn.net/Articles/682391/
来源 :https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt