intel_pstate CPU 性能调节驱动

版权所有:

© 2017 Intel Corporation

作者:

Rafael J. Wysocki <rafael.j.wysocki@intel.com>

常规信息

intel_pstate 是 Linux 内核中 CPU 性能调节子系统 (CPUFreq) 的一部分。它是用于 Sandy Bridge 及以后几代 Intel 处理器的调节驱动程序。但是,请注意,某些处理器可能不受支持。[要了解 intel_pstate,必须了解 CPUFreq 的一般工作原理,因此如果您尚未阅读 CPU 性能调节,现在是时候阅读了。]

对于 intel_pstate 支持的处理器,P-state 的概念比仅操作频率或操作性能点更广泛(有关更多信息,请参见 Kristen Accardi 在 2015 年欧洲 LinuxCon 上的演示文稿 [1])。因此,intel_pstate 在内部使用的 P-state 表示形式遵循硬件规范(有关详细信息,请参阅 Intel 软件开发人员手册 [2])。但是,CPUFreq 核心使用频率来标识 CPU 的操作性能点,并且频率涉及它公开的用户空间接口,因此 intel_pstate 也将其 P-state 的内部表示形式映射到频率(幸运的是,该映射是明确的)。同时,对于 intel_pstate 来说,由于其可能的大小,向 CPUFreq 核心提供可用频率表是不切实际的,因此驱动程序不这样做。核心的某些功能受到限制。

由于 intel_pstate 使用的硬件 P-state 选择接口在逻辑 CPU 级别可用,因此驱动程序始终与单个 CPU 一起工作。因此,如果正在使用 intel_pstate,则每个 CPUFreq 策略对象都对应于一个逻辑 CPU,并且 CPUFreq 策略实际上等效于 CPU。特别是,这意味着每次相应的 CPU 脱机时它们都会变为“非活动状态”,并且需要在返回在线状态时重新初始化。

intel_pstate 不是模块化的,因此无法卸载,这意味着将早期配置时间参数传递给它的唯一方法是通过内核命令行。但是,可以通过 sysfs 在很大程度上调整其配置。在某些配置中,甚至可以通过 sysfs 注销它,这允许加载和注册另一个 CPUFreq 调节驱动程序(请参见 below)。

操作模式

intel_pstate 可以在两种不同的模式下运行,即主动模式或被动模式。在主动模式下,它使用自己的内部性能调节调控器算法或允许硬件自行进行性能调节,而在被动模式下,它响应由通用 CPUFreq 调控器发出的请求,该调控器实现某种性能调节算法。哪种模式生效取决于使用了哪些内核命令行选项以及处理器的功能。

主动模式

对于具有硬件管理的 P-state (HWP) 支持的处理器,这是 intel_pstate 的默认操作模式。如果它在此模式下工作,则 sysfs 中所有 CPUFreq 策略的 scaling_driver 策略属性包含字符串“intel_pstate”。

在此模式下,驱动程序绕过 CPUFreq 的调节调控器层,并提供其自己的调节算法来选择 P-state。这些算法可以像通用调节调控器一样应用于 CPUFreq 策略(即,通过 sysfs 中的 scaling_governor 策略属性)。[请注意,可能会为不同的策略选择不同的 P-state 选择算法,但不建议这样做。]

它们不是通用调节调控器,但是它们的名称与某些调控器的名称相同。此外,令人困惑的是,它们通常与它们共享名称的通用调控器的工作方式不同。例如,intel_pstate 提供的 powersave P-state 选择算法不是通用 powersave 调控器的对应项(大致,它对应于 schedutilondemand 调控器)。

intel_pstate 在主动模式下提供两种 P-state 选择算法:powersaveperformance。它们的操作方式取决于处理器中是否已启用硬件管理的 P-state (HWP) 功能,并且可能取决于处理器型号。

默认使用哪种 P-state 选择算法取决于 CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE 内核配置选项。也就是说,如果设置了该选项,则默认情况下将使用 performance 算法,如果未设置该选项,则默认情况下将使用另一个算法。

具有 HWP 的主动模式

如果处理器支持 HWP 功能,则将在处理器初始化期间启用该功能,并且之后无法禁用该功能。可以通过在命令行中将 intel_pstate=no_hwp 参数传递给内核来避免启用该功能。

如果已启用 HWP 功能,则 intel_pstate 依赖于处理器自行选择 P-state,但它仍然可以向处理器的内部 P-state 选择逻辑提供提示。这些提示是什么取决于已应用于给定策略(或其对应的 CPU)的 P-state 选择算法。

即使 P-state 选择由处理器自动执行,intel_pstate 在此模式下也会向 CPU 调度程序注册利用率更新回调。但是,它们不用于运行 P-state 选择算法,而是用于定期更新当前 CPU 频率信息,以便从 sysfs 中的 scaling_cur_freq 策略属性获得。

HWP + performance

在此配置中,intel_pstate 将 0 写入处理器的能耗性能偏好 (EPP) 旋钮(如果支持)或其能耗性能偏差 (EPB) 旋钮(否则),这意味着处理器的内部 P-state 选择逻辑应完全专注于性能。

这将覆盖来自 sysfs 接口的 EPP/EPB 设置(请参见下面的 能耗与性能提示)。此外,在此配置中,任何尝试通过 sysfs 将 EPP/EPB 更改为与 0(“性能”)不同的值的尝试都将被拒绝。

此外,在此配置中,处理器内部 P-state 选择逻辑可用的 P-state 范围始终限制为上限(即,驱动程序允许使用的最大 P-state)。

HWP + powersave

在此配置中,intel_pstate 会将处理器的能耗性能偏好 (EPP) 旋钮(如果支持)或其能耗性能偏差 (EPB) 旋钮(否则)设置为先前通过 sysfs 设置的任何值(或者平台固件设置的任何默认值)。这通常会导致处理器的内部 P-state 选择逻辑对性能的关注较少。

没有 HWP 的主动模式

对于不支持 HWP 功能的处理器,或者在命令行中将 intel_pstate=no_hwp 参数传递给内核时,此操作模式是可选的。如果在命令行中将 intel_pstate=active 参数传递给内核,则在这些情况下使用主动模式。 [请注意,intel_pstate 永远不会拒绝使用任何启用了 HWP 功能的处理器。]

在此模式下,intel_pstate 向 CPU 调度程序注册利用率更新回调,以便运行 P-state 选择算法,即 powersaveperformance,具体取决于 sysfs 中的 scaling_governor 策略设置。这些利用率更新回调也会定期更新当前 CPU 频率信息,以便从 sysfs 中的 scaling_cur_freq 策略属性获得。

performance

如果没有 HWP,则无论处理器型号和平台配置如何,此 P-state 选择算法始终相同。

每次更新给定 CPU 的驱动程序配置时(例如,通过 sysfs),它都会选择允许使用的最大 P-state,但要受到通过 sysfs 设置的限制。

如果设置了 CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE 内核配置选项,则这是默认的 P-state 选择算法。

powersave

如果没有 HWP,则此 P-state 选择算法类似于通用 schedutil 调节调控器实现的算法,不同之处在于它使用的利用率指标基于来自 CPU 反馈寄存器的数字。通常,它选择与当前 CPU 利用率成比例的 P-state。

当 CPU 调度程序调用给定 CPU 的驱动程序的利用率更新回调时,会运行此算法,但频率不高于每 10 毫秒一次。与 performance 情况一样,如果新的 P-state 与当前 P-state 相同,则不会触及硬件配置。

如果未设置 CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE 内核配置选项,则这是默认的 P-state 选择算法。

被动模式

对于没有硬件管理的 P-state (HWP) 支持的处理器,这是 intel_pstate 的默认操作模式。如果将 intel_pstate=passive 参数传递给内核,则始终使用它,而不管给定的处理器是否支持 HWP。 [请注意,如果 intel_pstate=no_hwp 设置未与 intel_pstate=active 结合使用,则会导致驱动程序在被动模式下启动。] 与没有 HWP 支持的主动模式一样,在此模式下,如果通过内核命令行阻止启用 HWP,则 intel_pstate 可能会拒绝使用其无法识别的处理器。

如果驱动程序在此模式下工作,则 sysfs 中所有 CPUFreq 策略的 scaling_driver 策略属性都包含字符串“intel_cpufreq”。然后,驱动程序的行为类似于常规 CPUFreq 调节驱动程序。也就是说,必要时通用调节调控器会调用它来与硬件通信,以便更改 CPU 的 P-state(特别是,schedutil 调控器可以直接从调度程序上下文中调用它)。

在此模式下,intel_pstate 可以与 sysfsscaling_available_governors 策略属性列出的所有(通用)调节调控器一起使用(并且不使用上述 P-state 选择算法)。然后,它负责配置与 CPU 对应的策略对象,并向 CPUFreq 核心(以及附加到策略对象的调节调控器)提供有关硬件支持的最大和最小操作频率的准确信息(包括所谓的“turbo”频率范围)。换句话说,在被动模式下,intel_pstate 将所有可用的 P-state 范围公开给 CPUFreq 核心。但是,在此模式下,驱动程序不向 CPU 调度程序注册利用率更新回调,并且 scaling_cur_freq 信息来自 CPUFreq 核心(并且是当前调节调控器为给定策略选择的最后一个频率)。

Turbo P-state 支持

在大多数情况下,intel_pstate 可用的整个 P-state 范围可以分为两个子范围,它们对应于不同类型的处理器行为,高于和低于一个边界,该边界在下文中将被称为“turbo 阈值”。

高于 turbo 阈值的 P-state 被称为“turbo P-state”,它们所属的整个 P-state 子范围被称为“turbo 范围”。这些名称与 Turbo Boost 技术相关,该技术允许多核处理器在有足够的功率且不会导致超过处理器封装的热包络的情况下,机会性地增加一个或多个内核的 P-state。

具体来说,如果软件将 CPU 内核的 P-state 设置在 turbo 范围内(即,高于 turbo 阈值),则允许处理器接管该内核的性能调节控制,并使其进入其选择的 turbo P-state。但是,不同的处理器代系对该权限的解释不同。也就是说,Sandy Bridge 代系的处理器永远不会使用高于软件为给定内核设置的最后一个 P-state 的任何 P-state,即使它在 turbo 范围内,而所有后来的处理器代系都将其视为使用 turbo 范围内任何 P-state 的许可证,甚至高于软件设置的 P-state。换句话说,在这些处理器上,设置 turbo 范围内的任何 P-state 都将使处理器能够将给定内核置于所有 turbo P-state 中,直至并包括其认为合适的最高支持的 P-state。

turbo P-state 的一个重要特性是它们不可持续。更准确地说,无法保证任何 CPU 能够无限期地保持在任何这些状态中,因为处理器封装内的功率分配可能会随着时间的推移而变化,或者如果 turbo P-state 使用的时间过长,可能会超过其设计的散热包络。

反过来,低于 turbo 阈值的 P-state 通常是可持续的。事实上,如果软件设置了其中一个 P-state,则预计处理器不会将其更改为较低的 P-state,除非在热应力或违反功率限制的情况下(例如,如果同时为同一封装中的另一个 CPU 设置了更高的 P-state,则仍然可以使用更高的 P-state)。

某些处理器允许多个内核同时处于 turbo P-state 中,但可以为其设置的最大 P-state 通常取决于同时运行的内核数。可以同时为 3 个内核设置的最大 turbo P-state 通常低于 2 个内核的类似最大 P-state,而后者又通常低于可以为 1 个内核设置的最大 turbo P-state。因此,单核最大 turbo P-state 是总体支持的最大 P-state。

支持的最大 turbo P-state、turbo 阈值(支持的最大非 turbo P-state)和支持的最小 P-state 特定于处理器型号,可以通过读取处理器的特定于型号的寄存器 (MSR) 来确定。此外,某些处理器支持可配置 TDP(热设计功率)功能,并且在启用该功能时,turbo 阈值实际上变为可配置的值,可以由平台固件设置。

与 ACPI 表中的 _PSS 对象不同,intel_pstate 始终将整个可用 P-state 范围(包括整个 turbo 范围)公开给 CPUFreq 核心(以及被动模式下的通用调节调控器)。相对于基于 ACPI 的 CPU 性能调节,这通常会导致在使用 intel_pstate 时更频繁地设置 turbo P-state(有关更多信息,请参见下面的 acpi-cpufreq)。

此外,由于 intel_pstate 始终知道真正的 turbo 阈值是什么(即使在处理器中启用了可配置 TDP 功能),因此其 sysfs 中的 no_turbo 属性(如下面的 no-turbo 属性中所述)应在所有情况下都按预期工作(也就是说,如果设置为禁用 turbo P-state,则应始终阻止 intel_pstate 使用它们)。

处理器支持

为了处理给定的处理器,intel_pstate 需要知道许多不同的信息,包括

  • 支持的最小 P-state。

  • 支持的最大 非 turbo P-state

  • 是否完全支持 turbo P-state。

  • 支持的最大 单核 turbo P-state(如果支持 turbo P-state)。

  • 用于将驱动程序的 P-state 内部表示形式转换为频率以及反之的调节公式。

通常,获取该信息的方法特定于处理器型号或系列。尽管通常可以从处理器本身获取所有信息(使用特定于型号的寄存器),但在某些情况下,还需要查阅硬件手册才能获取该信息。

因此,intel_pstate 中有一个受支持的处理器列表,如果检测到的处理器不在该列表中,除非它支持 HWP 功能,否则驱动程序初始化将失败。[对于支持 HWP 功能的所有处理器,获取上述所有信息的接口都是相同的,这就是为什么 intel_pstate 可以与所有处理器一起工作。]

对混合处理器的支持

intel_pstate 支持的某些处理器包含两种或多种类型的 CPU 内核,这些内核的最大 turbo P-state、性能与功耗特性、缓存大小以及其他属性各不相同。它们通常被称为混合处理器。为了支持它们,intel_pstate 需要启用 HWP,并且它假定 HWP 性能单元对于系统中的所有 CPU 都是相同的,因此给定的 HWP 性能级别始终代表大致相同的物理性能,而不管内核 (CPU) 类型如何。

具有 SMT 的混合处理器

在至少一个内核上启用 SMT(同步多线程处理),在 Intel 处理器的上下文中也称为超线程 (HT) 的系统上,intel_pstate 会向 CPU 分配基于性能的优先级。也就是说,给定 CPU 的优先级反映了其最高的 HWP 性能级别,这会导致 CPU 调度程序通常更喜欢性能更高的 CPU,因此当其他 CPU 完全加载时,会使用性能较低的 CPU。但是,SMT 对等项(即,共享一个物理内核的逻辑 CPU)以特殊方式处理,以便如果其中一个正在使用中,则其他对等项的有效优先级将降低到其他物理内核中的 CPU 的优先级之下。

这种方法在大多数情况下最大限度地提高了性能,但不幸的是,它也导致在一些重要场景中过度使用能量,例如视频播放,这通常是不希望的。虽然在启用 SMT 的情况下没有其他可行的选择,因为 SMT 对等项的有效容量和利用率很难确定,但可以在更节能的方式下处理没有 SMT 的混合处理器。

容量感知调度支持

默认情况下,CPU 调度程序中的容量感知调度 (CAS) 支持由没有 SMT 的混合处理器上的 intel_pstate 启用。CAS 通常会导致调度程序将任务放在 CPU 上,只要其上有足够的备用容量,并且如果给定任务的利用率太高,则该任务将需要转移到其他位置。

由于 CAS 会考虑 CPU 容量,因此它不需要 CPU 优先级划分,并且它允许在性能更高和性能更低的 CPU 之间更对称地分配任务。一旦放置在具有足够容量容纳它的 CPU 上,任务就可以继续在那里运行,而不管其他 CPU 是否完全加载,因此平均而言,CAS 会降低性能更高的 CPU 的利用率,这会导致能量使用更加平衡,因为性能更高的 CPU 通常比性能更低的 CPU 的能源效率更低。

为了使用 CAS,调度程序需要知道系统中每个 CPU 的容量,并且需要能够计算 CPU 的缩放不变利用率,因此 intel_pstate 向其提供所需的信息。

首先,每个 CPU 的容量由其最高的 HWP 性能级别(乘以 1024)与系统中性能最高的 CPU 的最高 HWP 性能级别的比率表示,这样做是因为 HWP 性能单元对于所有 CPU 都是相同的。其次,由调度程序执行的频率不变性计算(始终以相同的单位表示 CPU 利用率,而不管其当前运行的频率如何)进行了调整,以考虑 CPU 容量。当 intel_pstate 已向 CPUFreq 核心注册自身并且它已经确定它正在没有 SMT 的混合处理器上运行时,所有这些都会发生。

能量感知调度支持

如果在内核配置期间已设置 CONFIG_ENERGY_MODEL,并且 intel_pstate 在没有 SMT 的混合处理器上运行,则除了启用 CAS 之外,它还会为处理器注册能量模型。如果使用 schedutil 作为 CPUFreq 调控器,这允许在 CPU 调度程序中启用能量感知调度 (EAS) 支持,这需要 intel_pstate被动模式下运行。

intel_pstate 注册的能量模型是人工的(也就是说,它基于抽象成本值,并且不包括任何实际功率数),并且它相对简单,可以避免调度程序中不必要的计算。在其中,对于系统中的每个 CPU 都有一个性能域,并且这些性能域的成本值的选择方式是,在性能较低(小型)CPU 上运行任务似乎总是比在性能更高(大型)CPU 上运行任务更便宜。但是,对于同一类型的两个 CPU,成本差异取决于其当前利用率,并且当前利用率较高的 CPU 通常似乎是给定任务的更昂贵的目标。这有助于平衡同一类型 CPU 之间的负载。

由于 EAS 在 CAS 之上工作,因此高利用率任务总是迁移到具有足够容量容纳它们的 CPU,但由于 EAS,低利用率任务倾向于放置在调度程序认为成本较低的 CPU 上。实际上,这会导致性能较低和负载较低的 CPU 成为首选,只要它们有足够的备用容量来运行给定的任务,这通常会导致降低能量使用。

可以通过查看 debugfs 中的 energy_model 目录来检查 intel_pstate 创建的能量模型(typlically 安装在 /sys/kernel/debug/ 上)。

sysfs 中的用户空间接口

全局属性

intel_pstatesysfs 中公开了几个全局属性(文件),以在系统级别控制其功能。它们位于 /sys/devices/system/cpu/intel_pstate/ 目录中,并影响所有 CPU。

如果将 intel_pstate=per_cpu_perf_limits 参数传递给内核,则其中一些属性不存在。

max_perf_pct

驱动程序允许设置的最大 P-state,以最大支持的性能级别(支持的最高 turbo P-state)的百分比表示。

如果内核命令行中存在 intel_pstate=per_cpu_perf_limits 参数,则不会公开此属性。

min_perf_pct

驱动程序允许设置的最小 P-state,以最大支持的性能级别(支持的最高 turbo P-state)的百分比表示。

如果内核命令行中存在 intel_pstate=per_cpu_perf_limits 参数,则不会公开此属性。

num_pstates

处理器支持的 P 状态数量(包括 0 到 255,包含 0 和 255),包括 Turbo 和非 Turbo P 状态(参见 Turbo P 状态支持)。

只有当该属性的值对于系统中所有 CPU 都相同时,才会显示此属性。

此属性的值不受 no_turbo 设置的影响,如下文 所述

此属性为只读。

turbo_pct

Turbo 范围大小与支持的 P 状态整个范围大小的比率,以百分比表示。

只有当该属性的值对于系统中所有 CPU 都相同时,才会显示此属性。

此属性为只读。

no_turbo

如果设置(等于 1),则驱动程序不允许设置任何 Turbo P 状态(参见 Turbo P 状态支持)。 如果未设置(等于 0,这是默认值),则驱动程序可以设置 Turbo P 状态。[请注意,intel_pstate 不支持通用的 boost 属性(某些其他调频驱动程序支持),此属性已由该属性替换。]

此属性不会影响提供给 CPUFreq 核心并通过策略接口公开的最大支持频率值,但它会影响每个策略 P 状态限制的最大可能值(有关详细信息,请参见下文 策略属性的解释)。

hwp_dynamic_boost

仅当 intel_pstate 在处理器中以 启用 HWP 功能的活动模式运行时,才会显示此属性。 如果设置(等于 1),则每当先前等待 I/O 的任务被选择在给定的逻辑 CPU 上运行时,都会导致最小 P 状态限制在短时间内动态增加(此机制的目的是提高性能)。

此设置对最小 P 状态限制直接设置为最高非 Turbo P 状态或高于该状态的逻辑 CPU 没有影响。

status

驱动程序的操作模式:“active”、“passive”或“off”。

“active”(活动)

驱动程序功能正常,并且处于 活动模式

“passive”(被动)

驱动程序功能正常,并且处于 被动模式

“off”(关闭)

驱动程序功能不正常(它未注册为 CPUFreq 核心的调频驱动程序)。

可以写入此属性以更改驱动程序的操作模式或取消注册。写入它的字符串必须是它的可能值之一,如果成功,写入将导致驱动程序切换到该字符串表示的操作模式,或者在“off”情况下取消注册。[实际上,从活动模式切换到被动模式或反之会导致驱动程序被取消注册并再次注册,并使用一组不同的回调,因此它的所有设置(全局设置以及每个策略的设置)都将重置为默认值,可能取决于目标操作模式。]

energy_efficiency(能效)

仅在具有与 Kaby Lake 或 Coffee Lake 桌面 CPU 型号匹配的 CPU 的平台上才会显示此属性。 默认情况下,如果启用了 HWP,则在这些 CPU 型号上会禁用能效优化。启用能效优化可能会限制启用或不启用 HWP 功能时的最大工作频率。如果启用了 HWP,则仅在 Turbo 频率范围内进行优化。如果未启用,则在整个可用频率范围内进行优化。将此属性设置为“1”会启用能效优化,设置为“0”会禁用优化。

策略属性的解释

如果 intel_pstate 是当前的调频驱动程序,则在 CPU 性能调频中描述的某些 CPUFreq 策略属性的解释是特殊的,并且通常取决于驱动程序的操作模式

首先,cpuinfo_max_freqcpuinfo_min_freqscaling_cur_freq 属性的值是通过将特定于处理器的乘数应用于 intel_pstate 使用的内部 P 状态表示来生成的。此外,scaling_max_freqscaling_min_freq 属性的值受驱动程序允许设置的最大 P 状态对应频率的限制。

如果设置了 no_turbo 全局属性,则驱动程序不允许使用 Turbo P 状态,因此 scaling_max_freqscaling_min_freq 的最大值限制为最大非 Turbo P 状态频率。因此,设置 no_turbo 会导致 scaling_max_freqscaling_min_freq 降低到该值(如果之前高于该值)。但是,取消设置 no_turbo 后,将恢复 scaling_max_freqscaling_min_freq 的旧值,除非在设置 no_turbo 后写入了这些属性。

如果未设置 no_turbo,则 scaling_max_freqscaling_min_freq 的最大可能值对应于最大支持的 Turbo P 状态,这也是任何情况下 cpuinfo_max_freq 的值。

接下来,如果 intel_pstate活动模式下工作,则以下策略属性具有特殊含义

scaling_available_governors

intel_pstate 提供的 P 状态选择算法列表。

scaling_governor

当前与给定策略一起使用的 intel_pstate 提供的 P 状态选择算法。

scaling_cur_freq

对于给定策略表示的 CPU,在 CPU 调度程序为该 CPU 上次两次调用驱动程序的利用率更新回调之间的时间间隔内,CPU 的平均 P 状态的频率。

如果在处理器中启用了 HWP 功能,则会显示另一个策略属性

base_frequency

显示 CPU 的基本频率。高于此频率的任何频率都将在 Turbo 频率范围内。

这些属性在被动模式下的含义与其他调频驱动程序相同。

此外,intel_pstatescaling_driver 属性的值取决于驱动程序的操作模式。即,它要么是“intel_pstate”(在 活动模式下),要么是“intel_cpufreq”(在 被动模式下)。

P 状态限制的协调

intel_pstate 允许通过两种方式设置 P 状态限制:借助 max_perf_pctmin_perf_pct 全局属性或通过 scaling_max_freqscaling_min_freq CPUFreq 策略属性。这些限制之间的协调基于以下规则,无论驱动程序的当前操作模式如何

  1. 所有 CPU 都受全局限制的影响(即,不能要求它们比全局最大值运行更快,也不能要求它们比全局最小值运行更慢)。

  2. 每个单独的 CPU 都受其自己的每个策略限制的影响(即,不能要求它比其自己的每个策略的最大值运行更快,也不能要求它比其自己的每个策略的最小值运行更慢)。有效性能取决于平台是否支持每个内核 P 状态,是否启用了超线程以及当前来自其他 CPU 的性能请求。当平台不支持每个内核 P 状态时,如果其他 CPU 当前请求更高的性能,则有效性能可能高于在 CPU 上设置的策略限制。即使支持每个内核 P 状态,当启用了超线程时,如果同级 CPU 请求更高的性能,则其他同级 CPU 将获得高于其策略限制的性能。

  3. 全局限制和每个策略的限制可以独立设置。

启用 HWP 功能的活动模式下,只要限制发生变化,结果有效值就会写入硬件寄存器,以便请求其内部 P 状态选择逻辑始终在这些限制内设置 P 状态。否则,缩放调控器(在 被动模式下)和驱动程序每次在为 CPU 设置新的 P 状态之前都会考虑这些限制。

此外,如果将 intel_pstate=per_cpu_perf_limits 命令行参数传递给内核,则根本不公开 max_perf_pctmin_perf_pct,并且设置限制的唯一方法是使用策略属性。

能耗与性能提示

如果在处理器中启用了硬件管理的 P 状态 (HWP),则在 sysfs 中的每个 CPUFreq 策略目录中都会显示其他属性,这些属性旨在允许用户空间帮助 intel_pstate 通过将其专注于性能或能效,或者介于两者之间的某个位置来调整处理器的内部 P 状态选择逻辑。

energy_performance_preference(能耗性能偏好)

给定策略(或由其表示的 CPU)的能耗与性能提示的当前值。

可以通过写入此属性来更改提示。

energy_performance_available_preferences(能耗性能可用偏好)

可以写入 energy_performance_preference 属性的字符串列表。

它们表示不同的能耗与性能提示,并且应该是自我解释的,除了 default 表示平台固件设置的任何提示值。

写入 energy_performance_preference 属性的字符串在内部转换为写入处理器能耗性能偏好 (EPP) 旋钮(如果支持)或其能耗性能偏差 (EPB) 旋钮的整数值。如果存在 EPP 功能,也可以写入 0 到 255 之间的正整数值。如果不存在 EPP 功能,则不支持将整数值写入此属性。在这种情况下,用户可以使用“/sys/devices/system/cpu/cpu*/power/energy_perf_bias”接口。

[请注意,任务可能会被调度程序的负载平衡算法从一个 CPU 迁移到另一个 CPU,并且如果为这些 CPU 设置了不同的能耗与性能提示,则可能会导致不良结果。为避免此类问题,最好为所有 CPU 设置相同的能耗与性能提示,或者将每个可能对它们敏感的任务固定到特定的 CPU。]

intel_pstateacpi-cpufreq

intel_pstate 支持的大多数系统上,平台固件提供的 ACPI 表包含 _PSS 对象,这些对象返回可用于 CPU 性能调频的信息(有关 _PSS 对象及其返回的信息格式的详细信息,请参阅 ACPI 规范 [3])。

ACPI _PSS 对象返回的信息由 acpi-cpufreq 调频驱动程序使用。在 intel_pstate 支持的系统上,acpi-cpufreq 驱动程序使用相同的硬件 CPU 性能调频接口,但它可以使用的 P 状态集受 _PSS 输出的限制。

在这些系统上,每个 _PSS 对象都返回一个由相应 CPU 支持的 P 状态列表,该列表基本上是可以由 intel_pstate 在同一系统上使用的 P 状态范围的子集,但有一个例外:整个 Turbo 范围由其中的一项(最上面的一项)表示。按照惯例,_PSS 为该项返回的频率比它列出的最高非 Turbo P 状态的频率高 1 MHz,但为此返回的相应 P 状态表示(遵循硬件规范)与支持的最大 Turbo P 状态匹配(或者是特殊值 255,实质上意味着“尽可能高”)。

_PSS 返回的 P 状态列表反映在 acpi-cpufreq 提供给 CPUFreq 核心和调频调控器的可用频率表中,并且它报告的最小和最大支持频率也来自该列表。特别是,考虑到上面描述的 Turbo 范围的特殊表示,这意味着 acpi-cpufreq 报告的最大支持频率比 _PSS 列出的最高支持非 Turbo P 状态的频率高 1 MHz,这当然会影响调频调控器做出的决定,除了 powersaveperformance

例如,如果给定的调控器尝试选择与估计的 CPU 负载成比例的频率,并将 100% 的负载映射到最大支持频率(可能乘以一个常数),那么如果 acpi-cpufreq 用作调频驱动程序,则它将倾向于选择低于 Turbo 阈值的 P 状态,因为在这种情况下,Turbo 范围对应于它可以使用的频段的一小部分(1 MHz 与 1 GHz 或更高)。因此,它只会为最高负载进入 Turbo 范围,而其他可能受益于以 Turbo 频率运行的 50% 以上的负载将被赋予非 Turbo P 状态。

另一个与此相关的问题可能会出现在支持 可配置 TDP 功能的系统上,该功能允许平台固件设置 Turbo 阈值。也就是说,如果这没有与 _PSS 返回的 P 状态列表正确协调,则这些列表中可能存在多个与 Turbo P 状态对应的项,并且可能会出现避免 Turbo 范围的问题(如果需要或必要)。通常,为了避免总体使用 Turbo P 状态,acpi-cpufreq 只是避免使用 _PSS 列出的最上面的状态,但这在它返回的列表中有其他 Turbo P 状态时是不够的。

除了上述情况外,acpi-cpufreq 的工作方式类似于 被动模式下的 intel_pstate,只是它可以设置的 P 状态数量仅限于 ACPI _PSS 对象列出的 P 状态。

intel_pstate 的内核命令行选项

可以使用多个内核命令行选项将早期配置时参数传递给 intel_pstate,以便强制执行其特定行为。所有这些选项都必须以 intel_pstate= 前缀开头。

disable(禁用)

即使处理器支持 intel_pstate,也不将其注册为调频驱动程序。

active(活动)

活动模式下注册 intel_pstate 以开始。

passive(被动)

被动模式下注册 intel_pstate 以开始。

force(强制)

即使在给定系统上首选 acpi-cpufreq,也将 intel_pstate 注册为调频驱动程序,而不是 acpi-cpufreq

这可能会阻止某些依赖于 ACPI P 状态信息可用的平台功能(例如散热控制和功耗限制)按预期运行,因此应谨慎使用。

此选项不适用于 intel_pstate 不支持的处理器以及使用 pcc-cpufreq 调频驱动程序而不是 acpi-cpufreq 的平台上。

no_hwp

即使处理器支持硬件管理的 P 状态 (HWP) 功能,也不启用该功能。

hwp_only

仅当处理器支持硬件管理的 P 状态 (HWP) 功能时,才将 intel_pstate 注册为调频驱动程序。

support_acpi_ppc

考虑 ACPI _PPC 性能限制。

如果 FADT(固定 ACPI 描述表)中的首选电源管理配置文件设置为“企业服务器”或“性能服务器”,则默认情况下会考虑 ACPI _PPC 限制,并且此选项不起作用。

per_cpu_perf_limits

使用每个逻辑 CPU 的 P 状态限制(有关详细信息,请参阅 P 状态限制的协调)。

no_cas

不要启用 容量感知调度,默认情况下在没有 SMT 的混合系统上启用该调度。

诊断和调整

跟踪事件

有两个静态跟踪事件可用于 intel_pstate 诊断。其中一个是通常由 CPUFreq 使用的 cpu_frequency 跟踪事件,另一个是特定于 intel_pstatepstate_sample 跟踪事件。只有当 intel_pstate活动模式下工作时,才会由 intel_pstate 触发这两个事件。

以下 shell 命令序列可用于启用它们并查看它们的输出(如果内核通常配置为支持事件跟踪)

# cd /sys/kernel/tracing/
# echo 1 > events/power/pstate_sample/enable
# echo 1 > events/power/cpu_frequency/enable
# cat trace
gnome-terminal--4510  [001] ..s.  1177.680733: pstate_sample: core_busy=107 scaled=94 from=26 to=26 mperf=1143818 aperf=1230607 tsc=29838618 freq=2474476
cat-5235  [002] ..s.  1177.681723: cpu_frequency: state=2900000 cpu_id=2

如果 intel_pstate被动模式下工作,则 cpu_frequency 跟踪事件将由 schedutil 调频调控器(对于它附加的策略)或由 CPUFreq 核心(对于具有其他调频调控器的策略)触发。

ftrace

ftrace 接口可用于 intel_pstate 的底层诊断。例如,要检查调用设置 P 状态的函数的频率,可以将 ftrace 过滤器设置为 intel_pstate_set_pstate()

# cd /sys/kernel/tracing/
# cat available_filter_functions | grep -i pstate
intel_pstate_set_pstate
intel_pstate_cpu_init
...
# echo intel_pstate_set_pstate > set_ftrace_filter
# echo function > current_tracer
# cat trace | head -15
# tracer: function
#
# entries-in-buffer/entries-written: 80/80   #P:4
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
            Xorg-3129  [000] ..s.  2537.644844: intel_pstate_set_pstate <-intel_pstate_timer_func
 gnome-terminal--4510  [002] ..s.  2537.649844: intel_pstate_set_pstate <-intel_pstate_timer_func
     gnome-shell-3409  [001] ..s.  2537.650850: intel_pstate_set_pstate <-intel_pstate_timer_func
          <idle>-0     [000] ..s.  2537.654843: intel_pstate_set_pstate <-intel_pstate_timer_func

参考