CPU 性能调整¶
- 版权:
© 2017 Intel Corporation
- 作者:
Rafael J. Wysocki <rafael.j.wysocki@intel.com>
CPU 性能调整的概念¶
大多数现代处理器都能够在多种不同的时钟频率和电压配置下运行,通常称为工作性能点或 P 状态(在 ACPI 术语中)。一般来说,时钟频率越高,电压越高,CPU 在单位时间内可以完成的指令就越多,但同时,时钟频率越高,电压越高,CPU 在给定 P 状态下单位时间内消耗的能量(或汲取的功率)就越多。因此,CPU 容量(单位时间内可以执行的指令数量)与 CPU 汲取的功率之间存在着一种自然的权衡。
在某些情况下,需要甚至必须尽可能快地运行程序,因此没有理由使用任何不同于最高 P 状态的 P 状态(即,可用的最高性能频率/电压配置)。然而,在某些其他情况下,可能没有必要如此快速地执行指令,并且在相对较长的时间内保持最高的可用 CPU 容量而不完全利用它可能被认为是浪费。由于散热或电源容量原因或类似原因,也可能无法在太长时间内保持最大 CPU 容量。为了涵盖这些情况,存在一些硬件接口,允许 CPU 在不同的频率/电压配置之间切换,或者(在 ACPI 术语中)进入不同的 P 状态。
通常,它们与算法一起用于估计所需的 CPU 容量,以便决定将 CPU 置于哪个 P 状态。当然,由于系统的利用率通常会随时间变化,因此必须定期重复此操作。发生这种情况的活动称为 CPU 性能调整或 CPU 频率调整(因为它涉及调整 CPU 时钟频率)。
Linux 中的 CPU 性能调整¶
Linux 内核通过 CPUFreq
(CPU 频率调整)子系统支持 CPU 性能调整,该子系统由三个代码层组成:核心层、调整调控器和调整驱动程序。
CPUFreq
核心层为所有支持 CPU 性能调整的平台提供通用的代码基础设施和用户空间接口。它定义了其他组件运行的基本框架。
调整调控器实现了用于估计所需 CPU 容量的算法。一般来说,每个调控器都实现一个可能参数化的调整算法。
调整驱动程序与硬件通信。它们向调整调控器提供有关可用 P 状态(或在某些情况下为 P 状态范围)的信息,并访问特定于平台的硬件接口以根据调整调控器的请求更改 CPU P 状态。
原则上,所有可用的调整调控器都可以与每个调整驱动程序一起使用。这种设计基于这样的观察:性能调整算法用于 P 状态选择的信息在大多数情况下可以用平台无关的形式表示,因此应该可以使用以完全相同的方式实现的相同性能调整算法,而不管使用哪个调整驱动程序。因此,同一组调整调控器应该适用于每个受支持的平台。
然而,对于基于硬件本身提供的信息的性能调整算法,例如通过反馈寄存器,该观察结果可能不成立,因为该信息通常特定于其来源的硬件接口,并且可能不容易以抽象的、平台无关的方式表示。因此,CPUFreq
允许调整驱动程序绕过调控器层并实现其自己的性能调整算法。这是由 intel_pstate 调整驱动程序完成的。
CPUFreq
策略对象¶
在某些情况下,P 状态控制的硬件接口由多个 CPU 共享。例如,同一个寄存器(或一组寄存器)用于同时控制多个 CPU 的 P 状态,并且写入该寄存器会同时影响所有这些 CPU。
共享硬件 P 状态控制接口的 CPU 集由 CPUFreq
表示为 struct cpufreq_policy 对象。为了保持一致性,当给定集合中只有一个 CPU 时,也使用 struct cpufreq_policy。
CPUFreq
核心层为系统中的每个 CPU 维护一个指向 struct cpufreq_policy 对象的指针,包括当前离线的 CPU。如果多个 CPU 共享同一个硬件 P 状态控制接口,则与它们对应的所有指针都指向同一个 struct cpufreq_policy 对象。
CPUFreq
使用 struct cpufreq_policy 作为其基本数据类型,并且其用户空间接口的设计基于策略概念。
CPU 初始化¶
首先,必须注册调整驱动程序才能使 CPUFreq
工作。一次只能注册一个调整驱动程序,因此调整驱动程序应该能够处理系统中的所有 CPU。
可以在 CPU 注册之前或之后注册调整驱动程序。如果 CPU 较早注册,则驱动程序核心层会调用 CPUFreq
核心层以记录在调整驱动程序注册期间所有已注册的 CPU。反过来,如果在调整驱动程序注册后注册了任何 CPU,则将调用 CPUFreq
核心层以在它们的注册时记录它们。
无论如何,只要 CPUFreq
核心层准备好处理该 CPU,它就会被调用以记录到目前为止它尚未看到的任何逻辑 CPU。[请注意,逻辑 CPU 可能是物理单核处理器,或者多核处理器中的单个核心,或者是物理处理器或处理器核心中的硬件线程。在下文中,“CPU”始终表示“逻辑 CPU”,除非另有明确说明,并且“处理器”一词用于指可能包括多个逻辑 CPU 的物理部分。]
一旦被调用,CPUFreq
核心层会检查是否已为给定的 CPU 设置了策略指针,如果是,则跳过策略对象的创建。否则,将创建一个新的策略对象并对其进行初始化,这涉及在 sysfs
中创建一个新的策略目录,并且与给定 CPU 对应的策略指针设置为内存中新策略对象的地址。
接下来,将调用调整驱动程序的 ->init()
回调,并将新 CPU 的策略指针作为参数传递给它。该回调应该初始化给定 CPU 的性能调整硬件接口(或者更准确地说,对于共享其所属硬件接口的 CPU 集合,由其策略对象表示),并且,如果已为其调用策略对象是新的,则设置策略的参数,例如硬件支持的最小和最大频率、可用频率表(如果支持的 P 状态集不是连续范围)以及属于同一策略的 CPU 掩码(包括在线和离线 CPU)。然后核心层使用该掩码来填充其中所有 CPU 的策略指针。
新策略对象的下一个主要初始化步骤是将调整调控器附加到它(首先,这是由内核命令行或配置确定的默认调整调控器,但稍后可以通过 sysfs
更改)。首先,将指向新策略对象的指针传递给调控器的 ->init()
回调,该回调应该初始化处理给定策略所需的所有数据结构,并可能向其添加调控器 sysfs
接口。接下来,通过调用其 ->start()
回调来启动调控器。
该回调应该向 CPU 调度程序注册给定策略的所有在线 CPU 的每个 CPU 利用率更新回调。CPU 调度程序将在重要事件(例如任务入队和出队)时,在调度程序节拍的每次迭代中或通常在 CPU 利用率可能发生变化时(从调度程序的角度来看)调用利用率更新回调。它们应该执行计算以确定要用于给定策略的 P 状态,并调用调整驱动程序以根据 P 状态选择对硬件进行更改。根据调整驱动程序和调控器的配置和功能,可以直接从调度程序上下文中或异步地通过内核线程或工作队列调用调整驱动程序。
对于不是新的但先前“不活动”的策略对象(这意味着属于它们的所有 CPU 都已离线),将采取类似的步骤。在这种情况下,唯一的实际区别是 CPUFreq
核心层将尝试使用先前与变为“不活动”(并且现在重新初始化)的策略一起使用的调整调控器,而不是默认调控器。
反过来,如果先前离线的 CPU 正在恢复联机,但与它共享策略对象的其他一些 CPU 已经联机,则根本不需要重新初始化策略对象。在这种情况下,只需要重新启动调整调控器,以便它可以将新的在线 CPU 考虑在内。这是通过按此顺序为整个策略调用调控器的 ->stop
和 ->start()
回调来实现的。
如前所述,intel_pstate 调整驱动程序绕过了 CPUFreq
的调整调控器层,并提供了它自己的 P 状态选择算法。因此,如果使用 intel_pstate,则调整调控器不会附加到新的策略对象。相反,将调用驱动程序的 ->setpolicy()
回调以注册每个策略的每个 CPU 利用率更新回调。这些回调由 CPU 调度程序以与调整调控器相同的方式调用,但在 intel_pstate 情况下,它们既确定要使用的 P 状态,又一次性地从调度程序上下文中相应地更改硬件配置。
在 CPU 初始化期间创建的策略对象和与其关联的其他数据结构在调整驱动程序注销时(例如,当包含它的内核模块被卸载时)或当给定策略中的最后一个 CPU 注销时被拆除。
sysfs
中的策略接口¶
在内核初始化期间,CPUFreq
核心层会在 /sys/devices/system/cpu/
下创建一个名为 cpufreq
的 sysfs
目录(kobject)。
该目录包含一个 policyX
子目录(其中 X
表示整数),用于 CPUFreq
核心层维护的每个策略对象。每个 policyX
目录都由 /sys/devices/system/cpu/cpuY/
下的 cpufreq
符号链接指向(其中 Y
表示整数,该整数可能与 X
表示的整数不同),用于与给定策略关联(或属于该策略)的所有 CPU。/sys/devices/system/cpu/cpufreq
中的 policyX
目录各自包含特定于策略的属性(文件),用于控制相应策略对象(即,与它们关联的所有 CPU)的 CPUFreq
行为。
其中一些属性是通用的。它们由 CPUFreq
核心层创建,并且它们的行为通常不取决于正在使用哪个调整驱动程序以及哪个调整调控器附加到给定策略。一些调整驱动程序还在 sysfs
中的策略目录中添加了特定于驱动程序的属性,以控制驱动程序行为的特定于策略的方面。
/sys/devices/system/cpu/cpufreq/policyX/
下的通用属性如下
affected_cpus
属于此策略的在线 CPU 列表(即,共享
policyX
策略对象表示的硬件性能调整接口)。bios_limit
如果平台固件 (BIOS) 指示操作系统对 CPU 频率应用上限,则将通过此属性(如果存在)报告该上限。
限制的存在可能是某些(通常是无意的)BIOS 设置、来自服务处理器的限制或其他基于 BIOS/HW 的机制的结果。
这不包括可以通过通用散热驱动程序发现的 ACPI 散热限制。
如果正在使用的调整驱动程序不支持此属性,则此属性不存在。
cpuinfo_cur_freq
从此策略所属的 CPU 的硬件获得的当前频率(以 KHz 为单位)。
预计这是硬件实际运行的频率。如果无法确定该频率,则不应存在此属性。
cpuinfo_avg_freq
从硬件提供的反馈中导出的属于给定策略的所有 CPU 的平均频率(以 KHz 为单位),并在跨越最多几毫秒的时间范围内报告。
预计这基于硬件实际运行的频率,因此可能需要专门的硬件支持(例如 ARM 上的 AMU 扩展)。如果无法确定,则不应存在此属性。
请注意,尝试检索给定 CPU 的当前频率失败将导致相应的错误,即:EAGAIN 对于保持空闲的 CPU(在 ARM 上引发)。
cpuinfo_max_freq
属于此策略的 CPU 可以运行的最大可能工作频率(以 kHz 为单位)。
cpuinfo_min_freq
属于此策略的 CPU 可以运行的最小可能工作频率(以 kHz 为单位)。
cpuinfo_transition_latency
将属于此策略的 CPU 从一个 P 状态切换到另一个 P 状态所花费的时间,以纳秒为单位。
如果未知,或者如果已知如此之高以至于调整驱动程序无法与 ondemand 调控器一起使用,则从该属性的读取将返回 -1 (
CPUFREQ_ETERNAL
)。related_cpus
属于此策略的所有(在线和离线)CPU 的列表。
scaling_available_frequencies
属于此策略的 CPU 的可用频率列表(以 kHz 为单位)。
scaling_available_governors
内核中存在的
CPUFreq
调整调控器的列表,可以附加到此策略,或者(如果正在使用 intel_pstate 调整驱动程序)驱动程序提供的可以应用于此策略的调整算法的列表。[请注意,某些调控器是模块化的,可能需要加载内核模块才能使其调控器可用并由此属性列出。]
scaling_cur_freq
属于此策略的所有 CPU 的当前频率(以 kHz 为单位)。
在大多数情况下,这是调整驱动程序使用它提供的调整接口从硬件请求的最后一个 P 状态的频率,由于硬件设计和其他限制,该频率可能无法反映 CPU 实际运行的频率。
某些架构(例如
x86
)可能会尝试通过此属性提供更精确地反映当前 CPU 频率的信息,但这仍然可能不是硬件当前看到的精确当前 CPU 频率。但是,此行为仅通过 c:macro:CPUFREQ_ARCH_CUR_FREQ
选项可用。scaling_driver
当前正在使用的调整驱动程序。
scaling_governor
当前附加到此策略的调整调控器,或者(如果正在使用 intel_pstate 调整驱动程序)驱动程序提供的当前应用于此策略的调整算法。
此属性是可读写的,写入它将导致将新的调整调控器附加到此策略,或者将调整驱动程序提供的新调整算法应用于它(在 intel_pstate 情况下),如写入此属性的字符串所指示的(该字符串必须是上面描述的
scaling_available_governors
属性列出的名称之一)。scaling_max_freq
允许属于此策略的 CPU 运行的最大频率(以 kHz 为单位)。
此属性是可读写的,将表示整数的字符串写入它将导致设置新的限制(它不得低于
scaling_min_freq
属性的值)。scaling_min_freq
允许属于此策略的 CPU 运行的最小频率(以 kHz 为单位)。
此属性是可读写的,将表示非负整数的字符串写入它将导致设置新的限制(它不得高于
scaling_max_freq
属性的值)。scaling_setspeed
仅当 userspace 调整调控器附加到给定策略时,此属性才起作用。
它返回调控器请求的最后一个频率(以 kHz 为单位),或者可以写入以设置策略的新频率。
通用调整调控器¶
CPUFreq
提供可与所有调整驱动程序一起使用的通用调整调控器。如前所述,它们中的每一个都实现一个可能参数化的性能调整算法。
调整调控器附加到策略对象,并且不同的策略对象可以由不同的调整调控器同时处理(尽管在某些情况下这可能会导致次优结果)。
可以使用 sysfs
中的 scaling_governor
策略属性随时更改给定策略对象的调整调控器。
某些调控器公开 sysfs
属性,以控制或微调它们实现的调整算法。这些属性称为调控器可调参数,可以是全局的(系统范围的)或每个策略的,具体取决于正在使用的调整驱动程序。如果驱动程序要求调控器可调参数为每个策略,则它们位于每个策略目录的子目录中。否则,它们位于 /sys/devices/system/cpu/cpufreq/
下的子目录中。在任何一种情况下,包含调控器可调参数的子目录的名称都是提供它们的调控器的名称。
performance
¶
当附加到策略对象时,此调控器会导致为该策略请求最高频率,该频率在 scaling_max_freq
策略限制内。
请求在当时一次发出,策略的调控器设置为 performance
,并在 scaling_max_freq
或 scaling_min_freq
策略限制在那之后更改时发出。
powersave
¶
当附加到策略对象时,此调控器会导致为该策略请求最低频率,该频率在 scaling_min_freq
策略限制内。
请求在当时一次发出,策略的调控器设置为 powersave
,并在 scaling_max_freq
或 scaling_min_freq
策略限制在那之后更改时发出。
userspace
¶
此调控器本身不执行任何操作。相反,它允许用户空间通过写入该策略的 scaling_setspeed
属性来设置其附加的策略的 CPU 频率。
schedutil
¶
此调控器使用从 CPU 调度程序获得的 CPU 利用率数据。它通常被视为 CPU 调度程序的一部分,因此它可以直接访问调度程序的内部数据结构。
它完全在调度程序上下文中运行,尽管在某些情况下,当它决定应该为给定策略更改 CPU 频率时,它可能需要异步调用调整驱动程序(这取决于驱动程序是否能够在调度程序上下文中更改 CPU 频率)。
此调控器对特定 CPU 的操作取决于为该 CPU 调用其利用率更新回调的调度类。如果是 RT 或截止时间调度类调用它,则调控器会将频率提高到允许的最大值(即 scaling_max_freq
策略限制)。反过来,如果是 CFS 调度类调用它,则调控器将使用给定 CPU 的根控制组的每个实体负载跟踪 (PELT) 指标作为 CPU 利用率估计(有关 PELT 机制的描述,请参阅 每个实体负载跟踪 LWN.net 文章 [1])。然后,根据以下公式计算要应用的新 CPU 频率
f = 1.25 *
f_0
*util
/max
其中 util
是 PELT 数,max
是 util
的理论最大值,f_0
是给定策略的最大可能 CPU 频率(如果 PELT 数与频率无关),或者当前 CPU 频率(否则)。
此调控器还采用一种机制,允许它临时提高最近一直在 I/O 上等待的任务的 CPU 频率,称为“I/O 等待提升”。当调度程序将 SCHED_CPUFREQ_IOWAIT
标志传递给调控器回调时,就会发生这种情况,这会导致频率立即上升到允许的最大值,然后随着时间的推移回落到上述公式返回的值。
此调控器仅公开一个可调参数
rate_limit_us
两个调控器计算的连续运行之间必须经过的最短时间(以微秒为单位)(默认值:调整驱动程序的转换延迟的 1.5 倍或最大 2 毫秒)。
此可调参数的目的是减少调控器的调度程序上下文开销,如果没有它,开销可能会过大。
此调控器通常被认为是较旧的 ondemand 和 conservative 调控器(如下所述)的替代品,因为它更简单且与 CPU 调度程序集成得更紧密,它在 CPU 上下文切换等方面的开销不太显着,并且它使用调度程序自己的 CPU 利用率指标,因此原则上它的决策不应与调度程序的其他部分做出的决策相矛盾。
ondemand
¶
此调控器使用 CPU 负载作为 CPU 频率选择指标。
为了估计当前 CPU 负载,它会测量其工作例程的连续调用之间经过的时间,并计算给定 CPU 未处于空闲状态的时间段的比例。非空闲(活动)时间与总 CPU 时间的比率被视为负载的估计值。
如果此调控器附加到多个 CPU 共享的策略,则会估计所有 CPU 的负载,并将最大结果作为整个策略的负载估计值。
此调控器的工作例程必须在进程上下文中运行,因此它是异步调用的(通过工作队列),并且如果需要,CPU P 状态会从那里更新。因此,此调控器的调度程序上下文开销是最小的,但它会导致相对频繁地发生额外的 CPU 上下文切换,并且由它触发的 CPU P 状态更新可能相对不规则。此外,它通过运行减少 CPU 空闲时间的代码来影响其自身的 CPU 负载指标(即使 CPU 空闲时间仅略微减少)。
它通常选择与估计负载成比例的 CPU 频率,以便 cpuinfo_max_freq
策略属性的值对应于负载 1(或 100%),并且 cpuinfo_min_freq
策略属性的值对应于负载 0,除非负载超过(可配置的)加速阈值,在这种情况下,它将直接达到它允许使用的最高频率(scaling_max_freq
策略限制)。
此调控器公开以下可调参数
sampling_rate
这是调控器的工作例程应该运行的频率,以微秒为单位。
通常,它设置为 2000(2 毫秒)量级的值。它的默认值是在此调控器附加到的每个策略上将
cpuinfo_transition_latency
增加 50% 的缓冲空间。最小值通常是两个调度程序节拍的长度。如果此可调参数是每个策略的,则以下 shell 命令将它表示的时间设置为转换延迟的 1.5 倍(默认值)
# echo `$(($(cat cpuinfo_transition_latency) * 3 / 2))` > ondemand/sampling_rate
up_threshold
如果估计的 CPU 负载高于此值(以百分比为单位),则调控器会将频率设置为策略允许的最大值。否则,所选频率将与估计的 CPU 负载成比例。
ignore_nice_load
如果设置为 1(默认值为 0),则会导致 CPU 负载估计代码将花费在执行“nice”级别大于 0 的任务上的 CPU 时间视为 CPU 空闲时间。
如果系统中存在在决定以什么频率运行 CPU 时不应考虑的任务,这可能很有用。然后,要实现这一点,只需将这些任务的“nice”级别提高到 0 以上,并将此属性设置为 1。
sampling_down_factor
临时乘数,介于 1(默认值)和 100 之间(包括 100),以应用于
sampling_rate
值,如果 CPU 负载高于up_threshold
。这会导致延迟调控器工作例程的下一次执行(在将频率设置为允许的最大值之后),因此频率在最长时间内保持在最大级别。
可以通过以维护最大 CPU 容量的额外能量为代价来避免某些突发性工作负载中的频率波动。
powersave_bias
应用于调控器的原始频率目标(包括估计的 CPU 负载超过
up_threshold
值时使用的最大值)的减少因子或 AMD 频率灵敏度节能偏置驱动程序 (drivers/cpufreq/amd_freq_sensitivity.c
) 的灵敏度阈值,介于 0 和 1000 之间(包括 0 和 1000)。如果未加载 AMD 频率灵敏度节能偏置驱动程序,则要应用的有效频率由下式给出
f * (1 -
powersave_bias
/ 1000)其中 f 是调控器的原始频率目标。在这种情况下,此属性的默认值为 0。
如果加载了 AMD 频率灵敏度节能偏置驱动程序,则此属性的默认值为 400,并且以不同的方式使用。
在 Family 16h(及更高版本)的 AMD 处理器上,有一种机制可以从硬件获取工作负载敏感度的测量值,范围为 0 到 100%(含)。该值可用于估计在 CPU 上运行的工作负载的性能如何响应频率变化。
敏感度为 0(内存密集型或 IO 密集型)的工作负载的性能预计不会因 CPU 频率的增加而有所提高,而敏感度为 100%(CPU 密集型)的工作负载如果 CPU 频率增加,预计性能会更好。
如果工作负载敏感度低于
powersave_bias
值所代表的阈值,则敏感度省电偏置驱动程序将导致调速器选择低于其原始目标的频率,从而避免过度配置那些无法从以更高 CPU 频率运行中受益的工作负载。
conservative
¶
此调控器使用 CPU 负载作为 CPU 频率选择指标。
它以与上面描述的 ondemand 调速器相同的方式估计 CPU 负载,但它实现的 CPU 频率选择算法是不同的。
也就是说,它避免在短时间内显着改变频率,这可能不适用于电源容量有限的系统(例如,电池供电)。为了实现这一点,它以相对小的步长,一次一步地向上或向下改变频率 - 这取决于估计的 CPU 负载是否超过了(可配置的)阈值。
此调控器公开以下可调参数
freq_step
频率步长,以调速器允许设置的最大频率(
scaling_max_freq
策略限制)的百分比表示,范围在 0 到 100 之间(默认为 5)。这是允许频率一次改变多少。 将其设置为 0 将导致使用默认频率步长(5%),将其设置为 100 实际上会导致调速器定期在
scaling_min_freq
和scaling_max_freq
策略限制之间切换频率。down_threshold
阈值(以百分比表示,默认为 20),用于确定频率变化的direction。
如果估计的 CPU 负载大于此值,频率将上升(
freq_step
)。如果负载小于此值(并且sampling_down_factor
机制未生效),频率将下降。否则,频率不会改变。sampling_down_factor
频率降低延迟因子,范围在 1(默认)到 10(含)之间。
它实际上导致频率下降的速度比上升的速度慢
sampling_down_factor
倍。
频率加速支持¶
背景¶
某些处理器支持一种机制,可以在某些条件下暂时(并且高于整个封装的可持续频率阈值)提高多核封装中某些内核的工作频率,例如,如果整个芯片没有被充分利用并且低于其预期的热或功率预算。
不同的供应商使用不同的名称来指代此功能。 对于 Intel 处理器,它被称为“Turbo Boost”,AMD 称其为“Turbo-Core”或(在技术文档中)“Core Performance Boost”等等。 通常,不同的供应商也以不同的方式实现它。 为了简洁起见,此处使用简单术语“频率加速”来指代所有这些实现。
频率加速机制可以是基于硬件的,也可以是基于软件的。 如果它是基于硬件的(例如,在 x86 上),则触发加速的决定由硬件做出(尽管通常它需要将硬件置于一种特殊状态,在该状态下它可以控制 CPU 频率在一定限制内)。 如果它是基于软件的(例如,在 ARM 上),则缩放驱动程序决定是否触发加速以及何时触发。
sysfs
中的 boost
文件¶
此文件位于 /sys/devices/system/cpu/cpufreq/
下,并控制整个系统的“加速”设置。 如果底层缩放驱动程序不支持频率加速机制(或者支持它,但提供了驱动程序特定的接口来控制它,例如 intel_pstate),则此文件不存在。
如果此文件中的值为 1,则频率加速机制已启用。 这意味着硬件可以置于可以触发加速的状态(在基于硬件的情况下),或者允许软件触发加速(在基于软件的情况下)。 这并不意味着当前系统中的任何 CPU 都在实际使用加速。 它仅表示使用频率加速机制的权限(由于其他原因可能永远不会使用)。
如果此文件中的值为 0,则频率加速机制已禁用且根本无法使用。
可以写入此文件的唯一值是 0 和 1。
加速控制旋钮的原理¶
频率加速机制通常旨在帮助在低于软件分辨率的时间尺度(例如,低于调度程序滴答间隔)上实现最佳 CPU 性能,并且对于许多工作负载来说,它显然是合适的,但在某些情况下可能会导致问题。
因此,许多系统可以在平台固件 (BIOS) 设置中禁用频率加速机制,但这需要重新启动系统才能根据需要调整设置,这至少在某些情况下可能不切实际。 例如
加速意味着超频处理器,尽管在受控条件下。 通常,处理器的能耗会随着频率和电压的升高而增加,即使是暂时的。 这在切换到容量有限的电源(例如电池)的系统上可能是不希望的,因此在系统运行时禁用加速机制的能力可能会有所帮助(但这取决于工作负载)。
在某些情况下,确定性行为比性能或能耗(或两者)更重要,因此在系统运行时禁用加速的能力可能会很有用。
为了检查频率加速机制本身的影响,最好能够在启用和禁用加速的情况下运行测试,最好在此期间不要重新启动系统。
运行基准测试时,可重复的结果非常重要。 由于加速功能取决于整个封装的负载,因此单线程性能可能会因此而变化,这有时会导致无法重现的结果。 可以通过在运行对该问题敏感的基准测试之前禁用频率加速机制来避免这种情况。
旧版 AMD cpb
旋钮¶
AMD powernow-k8 缩放驱动程序支持一个非常类似于全局 boost
的 sysfs
旋钮。 它用于禁用/启用某些 AMD 处理器的“核心性能加速”功能。
如果存在,该旋钮位于 sysfs
中的每个 CPUFreq
策略目录中(/sys/devices/system/cpu/cpufreq/policyX/
),并称为 cpb
,这表明了一个更精细的控制界面。 然而,实际的实现是在系统范围内进行的,并且为一个策略设置该旋钮会导致同时为所有其他策略设置相同的值。
该旋钮仍然在支持其底层硬件功能的 AMD 处理器上受支持,但可以从内核中配置出来(通过 CONFIG_X86_ACPI_CPUFREQ_CPB
配置选项),并且全局 boost
旋钮始终存在。 因此,始终可以使用 boost
旋钮代替 cpb
旋钮,强烈建议这样做,因为它与其他所有系统的做法更加一致(并且 cpb
旋钮将来可能不再受支持)。
对于任何没有底层硬件功能的处理器(例如,所有 Intel 处理器),cpb
旋钮永远不会存在,即使设置了 CONFIG_X86_ACPI_CPUFREQ_CPB
配置选项。