设计指南

此电脑热管理设计指南介绍了如何确定属于“过热”和“过冷”的电脑温度值。

进行这些确定是提供良好电脑用户体验的设计的一个重要要求。 此外,这些阈值可帮助为位于多个热区域中的电脑组件选择要执行的首选缓解操作。

设计温度阈值

变量和假设

以下因素会影响电脑的热行为:

  • 硬件设计

    优秀硬件设计的重要性怎么强调都不过分。 有关详细信息,请参阅硬件热建模和评估

  • 环境

    这些是导致系统热行为的外部因素。 软件只能通过向用户通知热约束是一个问题(例如通过显示“过热,无法启动”徽标)来影响环境。 用户必须移到不同的环境才能使这些因素发生变化:

    • 阳光辐射

      影响屏幕或系统任何部件的阳光的强度和角度。

    • 环境温度

      环境的温度。

    • Airflow

      带有或不带空气循环。 有风或是在计算机机箱中。

    • 湿度

      干燥或潮湿。

  • 工作负载和功耗

    此处的假设是,工作负载和功耗相互成比例。 换句话说,电脑或组件执行的工作越多,其功耗便越大,生成的热量便越多。 尽管这并非在所有情况下都是如此,但这种简化模型在此处或多或少是足够的。 这便是软件缓解措施的用武之地。 通过降低工作负载,可生成更少的热量,电脑也可保持运行。

对硬件进行设计和建模时,请考虑前面列表中提到的参数。 请对环境使用最坏情况值。 可以由软件直接控制的唯一参数是工作负载。

热基础知识

请考虑电脑在运行恒定工作负载时的热行为。 工作负载开始时,电脑的硬件组件(如 CPU 和 GPU)会生成热量并增加温度。 当温度相对于环境温度升高时,电脑会开始更快地散热,直到最终热量生成等于热量散发,并且温度达到稳定状态。 在此恒定工作负载的整个持续时间内,由于不涉及节流,因此性能和吞吐量是恒定的。

下图显示了在不涉及节流时,热量生成、温度和性能之间的关系。 请注意,电脑的温度始终处于热封套内,受环境温度和节流温度的限制。

heat, temperature, and performance with no throttling

现在考虑电脑在运行另一种工作负载时的热行为,该工作负载也是恒定的,但是占用的资源更多。 在此工作负载执行时,生成的热量远远高于系统能够散发到周围环境的热量,因此温度会稳定上升。 如果未进行被动冷却,温度会持续上升,直到系统最终变得过热,对最终用户的舒适性和安全性产生不利影响。 硬件在高温下也可能会损坏。 热节流可帮助确保电脑不会达到这类高温。 当温度上升到高于预定义节流温度跳变点时,系统会开始对性能进行节流。 因此,热量生成会减少,并且系统温度会逐渐达到稳定状态(在热量生成和散发平衡后)。

下图显示对性能进行节流以减少热量生成时的热量生成、温度和性能之间的关系。

heat, temperature, and performance with throttling

在以上图中显示的两种情况下,工作负载必须在热封套中运行,以确保系统温度不会超出安全限制。 封套从环境温度开始,以节流温度结束。 此外在这两种情况下,热量生成和散发最终会达到平衡状态,系统温度达到稳定。

定义热封套

设计良好的电脑应具有尽可能大的热封套,以便为用户提供持续时间较长的无需缓解体验。 如以上图中所示,热封套的下限由环境温度确定。 上限取决于节流温度。 虽然环境温度并不是系统设计人员可以控制的变量,但良好的硬件设计可以提高上限。 有关详细信息,请参阅硬件热建模和评估。 但即使是假设硬件不是主要限制,在定义热封套时也必须考虑其他重要因素。

在不影响这些限制因素的情况下,所需运行范围应尽可能大:

  • 安全性

    系统温度必须首先确保用户不会由于使用系统而遭受任何伤害。 此要求主要适用于外壳温度传感器。

  • 硬件保护

    温度应防止系统组件“融化”或是因热量导致损坏。 此要求主要适用于组件温度传感器(例如,位于处理器顶部的传感器)。

  • 政府法规

    所有系统都应符合适用的消费型电子产品安全性行业标准(例如 IEC 62368)。

硬件热建模和评估

软件作为硬件设计的补充

设计硬件时,牢记热管理至关重要。 选择低功率部件、使较热组件的位置相互远离以及引入热隔离只是硬件如何可以极大改善热体验的几个示例。 在软件中无法替代这些方法。 因此,软件解决方案在整体热体验中仅用作硬件设计的补充。

硬件目标

典型工作负载不应需要运行任何形式的软件热缓解措施。 硬件热设计应能够自行为这些工作负载进行散热。

建模

建模是一个迭代过程,用于实现前面所述的硬件目标。 在此过程中,请勿考虑任何软件缓解措施。 仅依赖于硬件功能,并根据需要进行调整。

  1. 定义典型工作负载。 根据系统的平台(从手机到服务器),每个系统都应具有一组标准典型工作负载。 这些不应是密集工作负载(如 HD 视频会议),而是更普通的工作负载(例如浏览 Web 或收听音乐)。

  2. 由于热量不会在机箱中均匀分布,因此在典型工作负载上对系统和各个组件功耗进行建模。 请特别注意功耗最高的组件(如处理器)。

  3. 根据工作负载功耗估算,对组件和外壳温度在一段时间内的上升进行建模。

  4. 调整系统的机械设计,以确保组件温度在所有环境温度下都处于硬件安全限制和用户舒适限制范围内。 一些用于解决机械设计问题的方法是:

    1. 通过添加更好的导热材料来改善散热能力。
    2. 通过添加隔离层,增加外壳与内部温度之间的温差。
  5. 重复步骤 1 到 4,直到得到满足。

  6. 构建硬件并进行评估。

Evaluation

对于每个硬件修订版,都必须执行针对典型工作负载进行的温度和功率测量以评估热行为,并应根据需要修改机械设计。

建议执行以下步骤来执行此类热评估:

  1. 定义热测量测试矩阵:

    1. 矩阵应涵盖正常和最大环境温度。
    2. 矩阵应包含作为热建模一部分标识的所有典型工作负载,并且对于每个工作负载,应捕获至少一小时的数据。
    3. 矩阵应在多台电脑中多次执行,以生成一致的结果。
  2. 对于测试矩阵中定义的每个工作负载,捕获以下数据:

    1. 系统和组件功耗数据。
    2. 环境、内部组件和外壳温度数据。
    3. 用于检测热节流、性能指标和处理器使用率的软件跟踪。

外壳和组件温度数据直接指示系统可能达到的最大外壳温度,以及此温度是否可接受。 考虑系统在紧急关闭之前可能有多少热空余空间。 性能指标数据会帮助确定系统是否在提供所需性能。 热节流软件记录的跟踪数据会显示热节流百分比。 功耗数据和 CPU 使用率数据可帮助确定影响温度变化的因素。

下表提供了针对具有以下配置的电脑的此类数据收集示例:

配置

  • 计算机名称:Thermal-Test-1
  • 平均环境温度:23oC
  • 热区域跳变点 (_PSV):80oC
类别 子类别 视频流 休闲游戏 鱼缸 3D 游戏 TDP
工作负载设置 通过 Wi-Fi 进行的全屏 720p H.264 视频流式传输

游戏名称

CPU 使用率

具有 100 条鱼的经典 IE

游戏名称

CPU 使用率

CPU 和 GPU 100%
功率消耗 系统电源
SoC 功率
显示器功率
背景光功率
温度 最大 SoC 温度
最大外壳温度
性能指标 平均帧速率 平均帧速率 平均帧速率 平均帧速率

Windows 热管理框架

Windows 热管理框架为软件热管理提供了全面的解决方案。 以下示例演示如何实现热管理。 通过适当的热建模、验证和高效的热机械设计,所有系统都应能够在大多数目标环境温度下对大多数工作负载提供流畅的用户体验。 在需要热缓解措施的情况下,Windows 提供有效且可扩展的热管理体系结构。

Windows 热管理支持主动和被动冷却。 使用主动冷却时,风扇会打开以循环空气并帮助冷却系统。 使用被动冷却时,设备会降低设备性能,以响应过热条件。 降低性能会降低功耗,从而生成更少的热量。

Windows 热管理框架依赖于系统设计人员指定的策略,以对系统强制实施热管理。 从较高层面来说,设计人员必须指定从每个热传感器获取的读数如何受每个组件影响。 如果不进行这些指定,Windows 便无法对系统进行热管理。 因此,每个系统设计人员需负责描述其系统的热特征,以便实现良好的热设计。

尽管系统不是必须使用 Windows 热管理框架,但建议使用该解决方案,因为它与操作系统紧密集成。 但是,无论使用何种热管理解决方案,所有新式待机电脑都必须遵循 HCK 要求以便进行诊断。

热管理体系结构

Windows 热管理体系结构基于“热区域”ACPI 概念。 ACPI 热区域模型需要固件、操作系统与驱动程序之间的协作。 此模型通过定义明确的接口将传感器和冷却设备从中央热管理组件中抽象化。 热管理增强功能基于 ACPI 5.0 规范的第 11 章。 Windows 热管理框架实现了本章中所述的一部分功能。

模型的基本组件包括:

  • 通过固件向 Windows 描述的平台热区域定义。 热区域是具有关联温度值的抽象实体。 操作系统会监视此温度,以便它可以对区域中的设备应用热缓解措施。 区域包含一组会生成热量的功能设备,以及一部分可通过调整性能来控制其热量生成的设备。
  • 表示区域温度的温度传感器。 传感器必须实现读取温度接口,以从固件或 Windows 温度驱动程序中检索区域温度。
  • 使热区域中设备的驱动程序可以实施被动冷却操作的热冷却接口。 每个受管理驱动程序必须具有冷却接口才能参与 Windows 热基础结构。
  • 集中式热管理器,它通过解释热区域定义以及在所需时间调用接口来协调冷却。 热管理器在 Windows 内核中实现,无需系统设计人员进行工作。

下面的框图是 Windows 热管理体系结构的概述。 主要组件是热管理器、热区域、受管理驱动程序和温度传感器。 热区域基于热管理器提供的约束决定其受管理设备的节流行为。 热管理器使用的算法使用热区域的传感器温度读数作为其输入参数。

overview of windows thermal management architecture

系统中的热区域必须在 ACPI 固件中进行描述,并通过 ACPI 向热管理器公开。 借助配置信息,热管理器知道需要管理的热区域数、何时开始对每个热区域进行节流以及属于相应区的设备。 为了监视温度,系统设计人员会在 ACPI 固件中为热通知提供支持。

当热管理器收到有关枚举区域中的热事件的通知时,它会开始定期评估该区域的温度,并确定要应用于热区域中设备的热节流性能百分比。 此评估通过 ACPI 规范中概述的热节流算法来完成。 热管理器随后会通知区域中的所有设备按特定百分比对性能进行节流,设备驱动程序会将节流百分比转换为特定于设备类的操作,以降低性能。 当热区域温度下降到低于节流阈值温度且无需进一步节流时,定期评估和节流会停止。

反馈循环

考虑热管理体系结构的另一种方式是从输入、策略控制器和受管理设备的角度。 在下面的框图中,反馈循环的输入是温度和电流。 这些输入用于确定要实现的热策略。 热管理器只依赖于温度输入,策略驱动程序可能会使用它所需的任何输入。 热区域随后会将该策略应用于其受管理驱动程序。 应用策略后,传感器会更新其值并关闭循环。

下面的框图显示热响应模型的三个阶段。 来自温度和电流传感器的输入可提供信息以帮助确定要应用的热策略。 此策略会应用于受管理驱动程序,这随后会影响传感器上的读数。 该过程会在反馈循环中重复。

the thermal response model

系统实施者的职责

如上所述,需要一些组件来实现完整的 Windows 热解决方案。 热框架的体系结构经过专门设计,以便可以分离硬件供应商和系统集成商的职责。

供合作伙伴实现的必需组件包括:

  • Sensors

    温度传感器驱动程序应由硬件供应商提供。 鉴于温度传感器不需要了解依赖它们的热区域,因此其功能应在不同平台设计间是标准的。 策略驱动程序的自定义传感器(例如电流传感器)也是硬件供应商的职责。

  • 热区域

    热区域可以由硬件供应商和/或系统集成商定义。 所有系统都必须具有至少一个实现紧急关闭温度(和休眠温度,如果支持)的热区域,这可以由硬件供应商或系统集成商完成。 但是,对于监视特定设备或外壳温度以进行缓解的其他热区域,系统集成商通常对系统的热行为有更具体的了解。 因此,这些热区域通常由系统集成商实现。

  • 设备驱动程序的热冷却接口

    为要进行热管理的设备编写驱动程序的开发人员也应是实现冷却接口的开发人员。 设备驱动程序使用此接口选择加入热管理框架。 设备驱动程序会对其设备的功能有具体了解。 这些相同驱动程序必须实现热冷却接口,以便它可以正确解释热区域请求的操作。

Sensors

传感器会提供输入以确定热策略应该是什么。 Windows 仅支持将温度传感器作为热管理器的输入。 但是,策略驱动程序还可以从自定义驱动程序(例如电流传感器驱动程序)获得输入。

温度传感器

温度传感器提供以下功能模式:

  • 持续监视温度变化,而不涉及热管理器或热区域。
  • 在温度超过由 _PSV、_HOT 或 _CRT 定义的阈值时通知热管理器。
  • 响应温度查询并返回当前温度值。

下图显示了温度监视在节流期间如何工作。 当温度达到预定义阈值(如 _PSV、_HOT 或 _CRT)时,ACPI 固件或温度传感器驱动程序应通知热管理器,然后响应来自热管理器针对当前温度的定期查询。 温度查询的周期由 _TSP 定义。

temperature monitoring and reporting

若要确保在温度超过阈值时始终通知热管理器,温度传感器中断应始终可唤醒(即使在系统处于新式待机以及 SoC 处于低功率状态时)。 如果温度传感器中断并不总是可唤醒,则至少应该将中断配置为电平触发,以避免潜在的中断丢失。

一个热传感器可由多个热区域使用,不过一个热区域中的热传感器不能超过一个。

建议传感器硬件应精确到 +/- 2oC。

有 _TMP 或温度传感器驱动程序报告的温度可能是传感器的实际值,或者是基于多个传感器的推断值。

这通常由硬件供应商提供。 Windows 支持两种用于监视温度的实现:

  • 温度传感器驱动程序
  • 基于 ACPI

实现 1:温度传感器驱动程序

温度传感器驱动程序只报告传感器的温度。 ACPI 驱动程序会向传感器驱动程序发出一个未完成 IOCTL,以检测是否越过其中一个跳变点。 此外,ACPI 可能会发出一个没有超时的 IOCTL,以读取当前温度。 如果在等待超时到期时取消读取 IOCTL,则传感器驱动程序应处理该取消。 温度传感器必须实现以下接口:

typedef struct _THERMAL_WAIT_READ {  
    ULONG Timeout;  
    ULONG LowTemperature;  
    ULONG HighTemperature;  
} THERMAL_WAIT_READ, *PTHERMAL_WAIT_READ;

#define IOCTL_THERMAL_READ_TEMPERATURE\  
        CTL_CODE(FILE_DEVICE_BATTERY, 0x24, METHOD_BUFFERED, FILE_READ_ACCESS)

下表介绍了温度读数接口的输入和输出参数。

参数 说明
超时

返回温度数据之前等待的时间(以毫秒为单位)。

0 表示应立即读取温度,无需等待。 -1 表示读取不会超时。
LowTemperature

返回新温度的阈值下限。 一旦温度低于温度阈值下限,驱动程序就应完成 IOCTL。 如果温度已低于温度下限,IOCTL 应立即完成。

HighTemperature

返回新温度的阈值上限。 一旦温度高于温度阈值上限,驱动程序就应完成 IOCTL。 如果温度已高于温度上限,则应立即完成 IOCTL。

IOCTL 返回值

ULONG 大小的输出缓冲区,将返回当前温度(以开氏度的十分之一表示)。

一个温度传感器可以由一个热区域或多个热区域使用。 若要指定应该用于热区域的温度传感器,热 _DSM 应在热区域上指定,并且应实现功能 2。 (为了向后兼容,可以将温度传感器驱动程序加载到热区堆栈的顶部。但是,首选实现是让传感器驱动程序与热区堆栈分开。此 _DSM 定义如下:

参数 Arg0:UUID = 14d399cd-7a27-4b18-8fb4-7cb7b9f4e500 Arg1:修订版 = 0 Arg2:功能 = 2 Arg3:空包 返回 对将返回热区域温度的设备的单个引用。

热区域还必须使用 _DEP 指定对温度传感器设备的依赖关系。 下面是传感器设备 _DSM 实现的简单示例。

Device(\_SB.TSEN) {
    Name(_HID, "FBKM0001")     // temperature sensor device
}

ThermalZone(\_TZ.TZ01) {
    Method(_DSM, 0x4, NotSerialized){
        Switch (ToBuffer(Arg0)) {
            Case (ToUUID("14d399cd-7a27-4b18-8fb4-7cb7b9f4e500")) {
                Switch (ToInteger(Arg2)) {
                    Case(0) {
                        // _DSM functions 0 and 2 (bits 0 and 2) are supported
                        Return (Buffer() {0x5})
                    }       
                    Case (2) {
                        Return ("\_SB.TSEN")
                    }
                }
            }
        }
    }

    Method(_DEP) {
        Return (Package() {\_SB.TSEN})
    }

    // Other thermal methods: _PSV, etc.

}

有关详细信息,请参阅 Microsoft 热量扩展的特定于设备的方法

实现 2:基于 ACPI

ACPI 固件应支持 _TMP 和 Notify 0x80(在 ACPI 规范中定义)。 此方法的优点是不需要在系统上安装任何其他驱动程序。 但是,此方法仅限于与可通过 ACPI 操作区域访问的资源进行交互。

热策略控制

热区域

热区域是单个热节流实体。 它具有自己的热节流特征,例如跳变点、节流采样率和节流公式常量。 一个热区域可能包括多个热节流设备,每个设备都可能会导致热区域的温度增加。 相同热区域的所有设备都必须遵循应用于热区域的相同约束。

若要确保准确定义热区域及其参数,系统设计人员应:

  • 确定系统机箱中的热点,并确定这些热点如何将热量散发到温度传感器。 (理想情况下,热传感器位于系统中的热点处,但外壳温度传感器除外。)
  • 描述系统温度关系的特征。 将温度传感器读数映射到组件温度和外壳温度。

过度节流阈值

从 Windows 10 开始,一种称为热区域状态的新功能已引入到 Windows 热管理中,并带有一种状态:过度节流。 当热区域超过设备的设计节流级别时,热管理器会向操作系统组件通知系统已过度节流。 此通知使系统可以减少工作负载以改善热状态。

热管理器会维护处于过度节流状态的热区域数的全局计数。 当计数高于零 (0) 时,热管理器会向系统发送 Windows 通知设施 (WNF) 通知,指示它已过度节流。 当过度节流区域数返回到零 (0) 时,热管理器会向系统发送另一个 WNF 通知,指示没有过度节流区域。

若要为热区域指定过度节流阈值,热 _DSM 应在热区域上指定,并实现功能 3。 此 _DSM 的定义如下:

参数 Arg0:UUID = 14d399cd-7a27-4b18-8fb4-7cb7b9f4e500 Arg1:修订版 = 0 Arg2:功能 = 3 Arg3:空包 返回 具有当前过度节流阈值的整数值,表示为百分比。

下面是一个指示区域过度节流的示例 _DSM,节流级别为 0% 到 49%。

 ThermalZone (TZ4) {
    Name (_HID, "QCOM24AE")
    Name (_UID, 0)
    Name(_TZD, Package (){\_SB.CPU4, \_SB.CPU5, \_SB.CPU6, \_SB.CPU7})
    Method(_PSV) { Return (3530) }
       Name(_TC1, 1)
       Name(_TC2, 1)
       Name(_TSP, 1)
       Name(_TZP, 0)
       // _DSM - Device Specific Method
       // Arg0: UUID Unique function identifier
       // Arg1: Integer Revision Level
       // Arg2: Integer Function Index (0 = Return Supported Functions)
       // Arg3: Package Parameters
       Method(_DSM, 0x4, NotSerialized) {
          Switch (ToBuffer(Arg0)) {
             Case (ToUUID("14d399cd-7a27-4b18-8fb4-7cb7b9f4e500")) {
                Switch (ToInteger(Arg2)) {
                   Case(0) {
                      // _DSM functions 0 and 3 (bits 0 and 3) are supported
                      Return (Buffer() {0x9})
                   }
                   Case (3) {
                      Return (50)  // overthrottled below 50%
                   }
                }
             }
          }
       }
 } // end of TZ4

在热区域引用中收到 Notify(0x81) 时会重新读取过度节流阈值。

实现 ACPI 对象

下表列出了需要在 ACPI 固件中实现以定义热区域的所有 ACPI 对象。

类别 控制方法
标识区域中包含的设备

_TZD

列出热区域中的设备。

_PSL

(可选)列出热区域中的处理器。 处理器可以改为包含在 _TZD 中(Windows 支持这两种实现)。

指定必须采取措施时的温度阈值

_PSV

开始节流时的温度。 有关详细信息,请参阅定义热封套

_HOT

(可选)操作系统使系统休眠时的温度。 对于不支持休眠的系统,操作系统会启动紧急关闭。 对于所有 x86/x64 系统,强烈建议对至少一个热区域使用此方法,因为休眠具有保存用户数据的好处。

_CRT

操作系统启动紧急关闭时的温度。 无用户模式通知。 系统上必须至少有一个热区域指定 _CRT。 否则,系统在系统达到临界温度时不会经历关闭路径。 相反,会达到固件防故障跳变点,可能会从操作系统中拔出电源。

描述被动冷却行为

_TC1

控制热管理器对温度变化应用热节流性能的力度。

_TC2

控制热管理器对当前温度与 _PSV 之间的温差应用热节流性能的力度。

_TSP

区域的适当温度采样间隔(以十分之一秒表示)。 热管理器会使用此间隔确定它评估热节流性能的频率。 必须大于零。 有关详细信息,请参阅热节流算法

描述主动冷却行为

_ACx

(可选)打开风扇时的温度。 必须按最高到最低的顺序排列,_AC0 为最高。

_ALx

主动冷却设备的列表。

设置主动/被动冷却策略

_SCP

(可选)用于设置用户的首选冷却策略(如果区域同时支持主动和被动冷却)。

最小节流限制

_DSM

使用 UUID:14d399cd-7a27-4b18-8fb4-7cb7b9f4e500 设置最小节流限制。 请注意,这是对于 Windows 热框架是自定义的,未在 ACPI 中定义。 有关详细信息,请参阅最小节流限制

报告温度

_TMP

读取热区域的温度。

_HID

用于加载 Windows 温度驱动程序的供应商唯一硬件标识符。

_DTI

(可选)用于向平台固件通知已超过某个区域的热阈值。 此方法通过更改区域的阈值来使固件可以实现滞后。

_NTT

(可选)用于指定也应通过 _DTI 向平台固件通知的显著温度变化。

通知热管理器

Notify 0x80

向操作系统通知已超过阈值 (_PSV)。 Windows 热管理器会开始热控制。

Notify 0x81

(可选)向操作系统通知区域的阈值已更改。 Windows 热管理器会自己更新以使用新值。 此方法通常用于实现滞后。

指定温度传感器设备

_DSM

使用 UUID:14d399cd-7a27-4b18-8fb4-7cb7b9f4e500。 有关详细信息,请参阅温度传感器

_DEP

加载温度传感器所引用的设备。

最小节流限制

最小节流限制是一种 Microsoft 热扩展 _DSM 方法,可为节流设备请求的 _PSV 创建下限。 换句话说,它可确定热区域对它控制的设备性能的限制程度。 如果存在,则会在启动时以及热区域收到 ACPI Notify (0x81) 的任何时候读取最小节流 _DSM。 在被动冷却算法的每次迭代中,以下内容用于计算热管理器应用于区域中设备的性能限制更改 (DP):

DP [%] = _TC1 × (Tₙ – Tₙ₋₁) + _TC2 × (Tₙ – Tₜ) 我们随后使用以下内容计算实际性能限制:

Pₙ = Pₙ₋₁ – DP 实施最小限制 (MTL) 后,第二个等式变为:

Pₙ = max(Pₙ₋₁ – DP, MTL) 若要为热区域指定最小节流限制,热 _DSM 应在热区域上指定,并实现功能 1。 此 _DSM 的定义如下:

参数 Arg0:UUID = 14d399cd-7a27-4b18-8fb4-7cb7b9f4e500 Arg1:修订版 = 0 Arg2:功能 = 1 Arg3:空包 返回 具有当前最小节流限制的整数值,表示为百分比。

下面是不小于 50% 的 _DSM 限制节流的简单示例。

ThermalZone(\_TZ.TZ01) {
    Method(_DSM, 0x4, NotSerialized) {
        Switch (ToBuffer(Arg0)) {
            Case (ToUUID("14d399cd-7a27-4b18-8fb4-7cb7b9f4e500")) {
                Switch (ToInteger(Arg2)) {
                    Case(0) {
                        // _DSM functions 0 and 1 (bits 0 and 1) are supported
                        Return (Buffer() {0x3})
                    }       
                    Case (1) {
                        Return (50)
                    }
                }
            }
        }
    }

内核中的热管理器

Windows 热管理器作为 Windows 内核的一部分实现。 它监视所有热区域的温度,并根据需要应用热节流。

每当热管理器查询 ACPI 驱动程序以获取当前温度时,它都会计算应该应用于热区域中所有热节流设备的热节流性能百分比。 当超过被动冷却阈值 (_PSV) 时,在每个温度采样间隔 (_TSP) 会评估并应用热限制,直到温度冷却到低于该阈值,热限制恢复为 100%。 硬件必须检测何时超过 _PSV,并且必须通过硬件 ACPI 事件通知发出相关信号。

热节流算法

热节流算法使用 ACPI 规范中定义的以下公式:

DP [%] = _TC1 × ( Tₙ – Tₙ₋₁ ) + _TC2 × (Tₙ – Tₜ) 其中

Tₙ = 热区域中温度传感器的当前温度读数(以开氏度的十分之一表示)。 Tₙ₋₁ = 上一个读数中的温度。 Tₜ = 目标温度(以开氏度的十分之一表示)(_PSV)。 DP = 所需性能更改。 这是介于 0(完全节流)与 100%(未节流)之间的线性值,这会应用于区域中的每个冷却设备。 此公式描述温度变化与节流性能之间的反馈循环。 在循环的每次迭代中,当前与上一个温度读数之间的温差要求性能 P 按 DP 百分比降低。 DP 值是要应用的热节流量。 许多冷却设备对冷却缓解措施没有线性热响应。 在这些设备中,热限制是向设备指示所需冷却量的提示。 每个冷却设备都具有其自己的映射,使此线性值映射到特定于设备的热缓解措施。 节流设备性能会减少功耗和热量生成,从而导致温度降低。

两个常量(_TC1 和 _TC2)控制在此反馈循环中应用热节流的力度。 _TC1 越大,用于维持稳定温度的热节流的力度便越大。 _TC2 越大,用于将温度下压到跳变点附近的热节流的力度便越大。

下表提供了有关热管理器如何计算并应用 DP 的示例。 此示例使用以下参数值:

配置

  • _PSV = 325oK
  • _TC1 = 2
  • _TC2 = 3
  • _TSP = 5000 毫秒
  • 假设温度持续每 5 秒上升 1 度。

下表中最右侧的列(标记为 P)指示强制执行这些参数指定的约束所导致的节流性能级别。

迭代 时间 Tₙ DP P
1 0 秒 326oK = 2 × 1 + 3 × 1 = 5% 95%
2 5 秒 327oK = 2 × 1 + 3 × 2 = 8% 87%
3 10 秒 328oK = 2 × 1 + 3 × 3 = 11% 76%
4 15 秒 320oK = 2 × 1 + 3 × 4 = 14% 62%
5 20 秒 330oK = 2 × 1 + 3 × 5 = 17% 45%
...

策略驱动程序

默认情况下,用于确定 ACPI 规范所规定的节流百分比的算法会用于所有热区域。 如前所述,此算法仅基于连接到热区域的温度传感器(可能会有限制)。

如果首选其他算法,则系统设计人员可以实现策略驱动程序以体现首选算法。 策略驱动程序位于它控制的区域的热区域堆栈顶部。 对于此区域,策略驱动程序的算法可用于在热管理器中替代 ACPI 算法。 策略驱动程序的算法能够将它可以访问的任何信息视为输入。 驱动程序做出的策略决策会传递给热管理器,后者会记录信息并传递给热区域进行执行。

将策略驱动程序用于热区域意味着策略驱动程序(而不是 ACPI 和操作系统)只负责决定何时对区域进行节流以及节流的程度。

如果存在策略驱动程序,则会完全忽略所有跳变点、所有热常量、最小节流限制等。 操作系统无法理解将热区域设置为其当前节流级别的原因。 使用策略驱动程序而不是属性解决方案有一些好处。 策略驱动程序会利用节流设备的内置进程。 热区域为提供热缓解措施而可以执行的任何操作都可以由策略驱动程序完成。 此外,会自动继承 Windows 热管理的诊断。

热策略接口已更新为包含一个用于指示区域是否过度节流的新参数。 此参数会初始化为 FALSE。 旧策略驱动程序不知道新参数,而新驱动程序在检测到策略版本“2”时会知道新参数受支持。

#define TZ_ACTIVATION_REASON_THERMAL      0x00000001  
#define TZ_ACTIVATION_REASON_CURRENT      0x00000002

#define THERMAL_POLICY_VERSION_1          1
#define THERMAL_POLICY_VERSION_2          2

typedef struct _THERMAL_POLICY {  
    ULONG           Version;  
    BOOLEAN         WaitForUpdate;  
    BOOLEAN         Hibernate;  
    BOOLEAN         Critical;  
    ULONG           ActivationReasons;  
    ULONG           PassiveLimit;  
    ULONG           ActiveLevel;
    BOOLEAN         OverThrottled;  
} THERMAL_POLICY, *PTHERMAL_POLICY;

策略驱动程序可以通过将 OverThrottled 参数设置为 TRUE 来完成策略 IOCTL,从而指示热区域过度节流。 当热条件改善时,热策略驱动程序随后可以通过将 OverThrottled 重置为 FALSE 来完成 IOCTL,以指示热区域已恢复。 在设置了过多节流标志后,Windows 不要求策略驱动程序进行节流。

受热管理的设备

热区域通过其内核模式驱动程序控制受管理设备的热行为。 一个热节流设备可能位于多个热区域中。 当多个热区域请求不同的热节流性能百分比时,热管理器会选取最小热节流性能百分比以应用于热节流设备。

许多冷却设备对冷却缓解措施没有线性热响应。 在这些情况下,热限制是向设备指示所需冷却程度的提示。 每个冷却设备都具有其自己的映射,使此线性值映射到其特定热缓解措施。

加载每个设备驱动程序时,ACPI 会查询热冷却接口,并将每个响应设备注册为冷却设备。 稍后,当被动冷却正在进行且区域的热限制已更改时,ACPI 会对区域中的每个冷却设备调用此接口。 冷却设备随后会将提供的热限制映射到其特定冷却特征,并实现适当的冷却缓解措施。 请注意,如果冷却设备出现在多个热区域中,则对设备约束最强的热限制(即最低百分比)会传递给设备。

注意 Windows 为处理器、背景光和 ACPI 控制方法电池提供热节流的内置实现。

热冷却接口

Windows 为设备驱动程序提供扩展点以注册为热节流设备并接收热节流百分比请求。 设备随后负责将该百分比转换为对自身有意义的操作。

要作为热节流设备添加的设备应首先将 _HID 添加到热区域热设备列表中,然后实现以下接口集。 加载每个设备驱动程序时,ACPI 会查询此接口,并将每个响应设备注册为冷却设备。 稍后,当被动冷却正在进行且区域的热限制已更改时,ACPI 会对区域中的每个冷却设备调用此接口。 冷却设备随后会将提供的热限制映射到其特定冷却特征,并实现适当的冷却缓解措施。 请注意,如果冷却设备出现在多个热区域中,则对设备约束最强的热限制(即最低百分比)会传递给设备。

//  
// Thermal client interface (devices implementing  
// GUID_THERMAL_COOLING_INTERFACE)  
//

typedef  
_Function_class_(DEVICE_ACTIVE_COOLING)  
VOID  
DEVICE_ACTIVE_COOLING (  
    _Inout_opt_ PVOID Context,  
    _In_ BOOLEAN Engaged  
    );  

typedef DEVICE_ACTIVE_COOLING *PDEVICE_ACTIVE_COOLING;  

typedef  
_Function_class_(DEVICE_PASSIVE_COOLING)  
VOID  
DEVICE_PASSIVE_COOLING (  
    _Inout_opt_ PVOID Context,  
    _In_ ULONG Percentage  
    );  

typedef DEVICE_PASSIVE_COOLING *PDEVICE_PASSIVE_COOLING;  

typedef struct _THERMAL_COOLING_INTERFACE {  
    //  
    // generic interface header  
    //  
    USHORT Size;  
    USHORT Version;  
    PVOID Context;  
    PINTERFACE_REFERENCE    InterfaceReference;  
    PINTERFACE_DEREFERENCE  InterfaceDereference;  
    //  
    // Thermal cooling interface  
    //  
    ULONG Flags;  
    PDEVICE_ACTIVE_COOLING ActiveCooling;  
    PDEVICE_PASSIVE_COOLING PassiveCooling;  
} THERMAL_COOLING_INTERFACE, *PTHERMAL_COOLING_INTERFACE;  

#define THERMAL_COOLING_INTERFACE_VERSION 1

处理器

对于处理器,热管理器会将热节流百分比传达给处理器电源管理器 (PPM)。 处理器的热节流是 Windows 的内置功能。

处理器聚合器

处理器聚合器设备允许将“内核休止”作为热缓解措施。 如果处理器聚合器设备是热区域的成员,则区域可以将内核休止指定为热缓解措施。 处理器无需节流,即可进行内核休止。 此实现与逻辑处理器空闲 (LPI) 并行工作。 请注意,这仍需遵循内核休止的注意事项。 具体而言,与已休止内核关联的任何工作都会导致内核运行。

Device(\_SB.PAGR) {
    Name(_HID, "ACPI000C")
}
ThermalZone(\_TZ.TZ01) {
    Name(_TZD, Package() {"\_SB.PAGR"})
    // Other thermal methods: _PSV, etc.
}

显卡

若要对第三方图形微型端口驱动程序进行热管理,它必须与 Windows 图形端口驱动程序 Dxgkrnl.sys 交互。 Dxgkrnl.sys 具有热冷却接口,并且将任何节流请求沿堆栈向下传递给微型端口驱动程序。 由微型端口驱动程序负责将请求转换为特定于其设备的操作。

下面的框图显示了控制 GPU 的热区域体系结构。

architecture for thermal zone controlling a gpu

背光

减少背景光可以显著改善移动平台上的热条件。 Windows 建议在工作时,对系统显示器的热限制不得导致其亮度低于 100 尼特。

对于背景光控制,热管理器会将热节流百分比传达给监视器驱动程序 Monitor.sys。 Monitor.sys 会基于此热输入和 Windows 中的其他输入来确定实际背景光级别设置。 Monitor.sys 随后会通过 ACPI 或显示驱动程序应用背景光级别设置。

请注意,如果包含背景光的热区域温度持续上升,则请求的热节流百分比最终可能会下降到 0%。 ACPI 或显示驱动程序中的背景光级别实现应确保最终用户仍可看到可用于性能控制的最小亮度级别。

注意 在工作时,对系统显示器的热限制不得导致其亮度低于 100 尼特。

Battery

系统中的另一个主要热源是电池充电。 从用户的角度来看,在受约束热条件下,应减少甚至完全停止充电。 但是,在正常使用情形下,不应妨碍电池充电。

注意 建议在系统处于以下条件时不对电池充电进行节流:(1) 空闲且环境温度范围低于 35oC,或 (2) 在环境温度低于 25oC 时的任何条件下。

如上所述,Windows 控制方法电池微型类驱动程序 Cmbatt.sys 直接使用热冷却接口。 固件负责在充电时考虑当前热限制。 需要新 ACPI 控制方法来为充电设置热限制。 此方法作为特定于设备的方法 (_DSM) 来实现(按照 ACPI 5.0 规范第 9.14.1 节中的定义)。

若要应用热节流百分比,Cmbatt.sys 会评估特定于设备的方法 (_DSM) 控制方法,以请求 ACPI 固件来为充电设置热限制。 在 _DSM 控制方法中,定义了 GUID 来指示热限制。

参数号 说明
Arg0 4c2067e3-887d-475c-9720-4af1d3ed602e UUID
Arg1 0 修订
Arg2 1 函数
Arg3 介于 0 至 100 之间的整数值 电池充电的热限制。 等于计算的被动节流百分比。
返回值 空值 无返回值

主动冷却

从操作系统的角度来看,平台有两种策略可用于实现风扇控制:

  • 实现具有主动跳变点的一个或多个 ACPI 热区域,以接通/断开风扇。

    Windows 热框架在非常基本的级别上支持主动冷却设备。 内置支持的唯一设备是 ACPI 风扇,它只能使用开/关信号进行控制。

  • 实现专有解决方案来控制风扇(通过驱动程序、嵌入式控制器等)。

    尽管 Windows 不控制风扇专有解决方案的行为,但 Windows 对所有实现(包括嵌入式控制器)都支持向风扇管理器发送风扇通知,以便可以收集诊断信息和遥测。 因此,向操作系统公开风扇对于所有新式待机电脑都是必需的,并强烈建议用于所有其他电脑。

请注意,主动冷却的实现与前面讨论的被动冷却缓解措施完全分隔。

由 ACPI 热区域进行的风扇控制

Windows 支持 ACPI 1.0 基于 D-state 的风扇定义。 (有关详细信息,请参阅 ACPI 规范。因此,控件仅限于风扇“开”和“关”状态。 风扇的驱动程序在 Windows ACPI 驱动程序 Acpi.sys 中提供。

  1. 温度传感器读取温度已超过跳变点,并对关联热区域发出 Notify(0x80)。
  2. 热区域使用 _TMP 控制方法读取温度,并将温度与主动跳变点 (_ACx) 进行比较以确定是需要打开还是关闭风扇。
  3. 操作系统将风扇设备置于 D0 或 D3 状态,这会导致风扇打开或关闭。

下面的框图显示了由 ACPI 热区域控制的风扇的控制流。

control flow for a fan controlled by an acpi thermal zone

Scope(\_SB) {
    Device(FAN) {
        Name(_HID, EISAID("PNP0C0B"))
        // additional methods to turn the fan on/off (_PR0, etc.)
    }

    ThermalZone(TZ0) {
        Method(_TMP) {...}
        Name(_AC0, 3200)
        Name(_AL0, Package() {\_SB.FAN})
    }
}

ACPI 中的多速风扇

若要使用 ACPI 1.0 为风扇实现多个速度,有两个选项:

  • 当只有一个物理风扇存在时,热区域可以包含多个“风扇”。 一次打开更多“风扇”表示加快风扇速度。 有关详细信息,请参阅 ACPI 5.0 规范第 11.7.2 节中的此选项示例。
  • 风扇打开后,它可以自行决定旋转速度。 例如,具有嵌入式控制器的系统可以选择此选项。

风扇专有解决方案

Windows 需要能够使用任一实现检测风扇活动。 当平台使用 ACPI 热模型时,Windows 负责打开和关闭风扇,因此已知道风扇何时处于活动状态。 当专有解决方案用于控制风扇时,Windows 需要有关风扇正在运行的通知。 为了实现此功能,Windows 会支持下表中列出的 ACPI 4.0 风扇扩展的部分子集。

功能 说明 支持
_FST 返回风扇的状态。
Notify(0x80) 指示风扇的状态已更改。
_FIF 返回风扇设备信息。
_FPS 返回风扇性能状态的列表。
_FSL 设置风扇性能状态(速度)。

Windows 会使用 _FST 对象确定风扇是正在运行(控制字段为非零)还是关闭(控制字段为零)。 Windows 还会对风扇设备支持 Notify(0x80),用于指示 _FST 已更改且需要重新评估。

实现 _FST 对象的风扇不需要处于热区域的 _ALx 设备列表中,但作为一个选项,它可以在此列表中。 此选项可实现混合解决方案,其中风扇通常由第三方驱动程序控制,但如果未安装第三方驱动程序,则可以由 OS 热区域控制。 如果风扇处于 _ALx 设备列表中,并且由热区域接通(置于 D0),则 _FST 对象需要指示非零控制值。

对于所有风扇,Windows 会使用以下算法确定风扇的状态:

  1. 如果风扇处于 D0(由于超过热区域的 _ACx 跳变点),则它已接通。
  2. 如果风扇处于 D3,并且不支持 ACPI 4.0 扩展,则它已断开。
  3. 如果风扇处于 D3 并支持 ACPI 4.0 扩展,则操作系统会检查 _FST 的控制字段是否具有非零值,以查看风扇是否已接通。

示例 1:硬件风扇控制

在此示例中,风扇由嵌入式控制器控制。

  1. 嵌入式控制器基于其自己的内部算法来确定启动或停止风扇。
  2. 在启动或停止风扇后,嵌入式控制器会对风扇设备发出 Notify(0x80)。
  3. 操作系统会评估 _FST 并读取风扇的新状态。

下面的框图显示了由嵌入式控制器控制的风扇的控制流。

control flow for a fan controlled by an embedded controller

以下 ASL 示例定义了一个“风扇”设备,该设备可以向操作系统通知风扇状态的更改:

Scope(\_SB) {
    Device(FAN) {
        Name(_HID, EISAID("PNP0C0B"))
        Name(_FST, Package() {0, 0, 0xffffffff})

        // \_SB.FAN.SFST called by EC event handler upon fan status change
        Method(SFST, 1) {
            // Arg0 contains the new fan status
            Store(Arg0, Index(_FST, 1))
            Notify(\_SB.FAN, 0x80)
        }
    }

    // Omitted: EC event handler
}

示例 2:驱动程序风扇控制

在此示例中,第三方驱动程序在控制风扇。

  1. 驱动程序基于其自己的内部算法来确定启动或停止风扇。
  2. 驱动程序会修改风扇的状态,并对其热设备评估自定义控制方法 (SFST)。
  3. 热设备控制方法会更新风扇设备的 _FST 内容并对风扇设备发出 Notify(0x80)。
  4. 操作系统会评估 _FST 并读取风扇的新状态。

下面的框图显示了由第三方驱动程序控制的风扇的控制流。

control flow for a fan controlled by a third-party driver

Scope(\_SB) {
    Device(FAN) {
        Name(_HID, EISAID("PNP0C0B"))
        Name(_FST, Package() {0, 0, 0xffffffff})
    }

    Device(THML) {
        Name(_HID, "FBKM0001")
        Method(SFST, 1) {
            // Arg0 contains the new fan status
            Store(Arg0, Index(\_SB.FAN._FST, 1))
            Notify(\_SB.FAN, 0x80)
        }
    }
}

风扇状态

平台通过在 ACPI 命名空间中包含风扇设备 (PnP ID PNP0C0B) 来指示系统中存在风扇。 Windows 会将此设备的存在用于指示系统具有风扇,而缺少此设备指示系统没有风扇。

特定于新式待机的指导

Windows 热管理框架是内核的一部分,随所有 Windows 系统附带。 因此,以上资料适用于所有计算机。 但是,不同类型的计算机需要更特定于新式待机的其他指导。

新式待机将智能手机电源模型引入电脑。 它提供了用户在其手机上期待的即时打开、即时关闭用户体验。 正如在手机上一样,新式待机使系统只要有合适的网络可用,便可保持新鲜、最新且可访问。 Windows 10 支持满足特定 Windows 认证要求的低功率平台上的新式待机。

新式待机电脑是采用轻薄外形规格的高度移动设备。 此外,新式待机电脑始终打开并处于 ACPI S0 状态。 为了提供强大可靠的客户体验,整个系统(从机械设计到固件和软件实现)必须在设计时特别注意热特征。 因此,所有新式待机电脑都必须符合热要求。

新式待机要求

所有新式待机电脑都必须通过以下 HCK 测试:

  • 所有新式待机电脑都必须至少有一个定义了紧急关闭温度 (_CRT) 的热区域。 对于 x86 系统,建议定义紧急休眠温度 (_HOT) 以触发用户数据的保存。 _HOT 必须低于 _CRT,_CRT 应低于固件防故障热跳变点。
  • 每个热区域都必须报告传感器中的实际温度 (_TMP)。 该测试在电脑上运行不同的工作负载,并且温度应发生变化。

此外,建议每台电脑至少包含一个用于 SoC 的温度传感器。

主动冷却要求

使用风扇的新式待机电脑必须遵循在 HCK 中测试的以下额外要求:

  • 风扇必须向操作系统公开。 有关详细信息,请参阅风扇状态
  • 操作系统必须始终知道风扇是打开还是关闭。 即使在新式待机中处于空闲复原期间,风扇活动的任何变化也必须唤醒 SoC 以更新状态。 有关实现风扇通知的详细信息,请参阅由 ACPI 热区域进行的风扇控制
  • 当电脑处于新式待机时,风扇不得打开。 在新式待机期间(每当屏幕关闭时)存在真实工作负载时,风扇不得打开。

从用户的角度来看,当电脑处于新式待机时,它会显示为关闭状态。 用户期望处于新式待机的电脑的行为如同它处于“睡眠”状态时一样。 因而,用户期望风扇从不打开,正如在睡眠期间的传统电脑一样。 如果风扇确实打开,则用户可能会听到它和/或感觉热空气循环,并认为计算机运行不正常。 因此,在处于新式待机期间,风扇不应打开。 有关所需行为的详细信息,请参阅新式待机电脑的 HCK 测试要求

这些要求意味着屏幕打开时的冷却策略可能需要与屏幕关闭时不同。 在屏幕打开期间,电脑可能会使用主动冷却,但在屏幕关闭时它必须仅依赖于被动冷却。 当屏幕打开时,风扇的主动跳变点可能比屏幕关闭时低得多。 对于 ACPI 实现,_ACx 必须在进入新式待机时进行更新。 对于专有解决方案,请确保在嵌入式控制器中更新策略。

处理器节流

PPM 会将最大、所需和最小性能级别传达给 PEP。 在温度节流条件下,最大性能级别应等于热量管理器请求的节流性能。 PEP 随后基于 PPM 的性能级别要求设置 CPU 的物理电压和频率。


风扇噪音信号

从 Windows 11 开始,设备可以将风扇噪音信号发送到 OS,以供在资源管理决策中使用,目的是为用户提供凉爽安静的体验。 此选择加入接口允许固件将风扇 RPM 信息以从 0(风扇关闭)到最大 RPM 的值的方式发送到 OS,从而 OS 可以在资源管理决策中使用该信息来根据需要冷却设备。 这有助于实现两大优势:

  1. 安静的用户体验:风扇噪音和热风吹扫是客户不满的重要因素。 特别是在用户不希望有大量风扇活动的时候,例如设备运行少量工作或没有前台工作时。
  2. 延长了电池使用时间:更高的风扇速度导致耗电量增加,这会导致在 DC 上电池消耗更快,同时在 AC 上充电速度较慢。

目前,此信号可用于管理搜索索引器任务,同时还计划启用其他后台任务来使用此信号。

下图总结了如何在从固件到软件的各层中发送风扇噪音信号。

Diagram summarizing how fan noise signal is sent from firmware to software

风扇噪音信号的工作原理

ACPI 接口详细信息

下面是用于支持此功能的设备特定方法(_DSM、UUID:A7611840-99FE-41ae-A488-35C75926C8EB)的四个功能。 有关 _FST(风扇状态)的信息,请参阅 ACPI 规范的第 11.3.1.4 部分和示例 1:热管理设备的硬件风扇控制

下图总结了如何使用这些函数的流程。

Diagram summarizing the flow of how these functions are used.

下面的框图显示了由嵌入式控制器控制的风扇的控制流程,包括 Notify(0x80) 控制方法。

注意

风扇噪音信号不会控制风扇 RPM,而是通知 OS 存在需要从后台任务移动 CPU 资源才能完成优先级工作的风扇噪音。

Fan control flow


枚举函数(函数 0)

若要使操作系统与平台交互,必须通过命名空间公开 ACPI 设备。 本设备必须包括包含 EISAID(“PNP0C0B”)的 _CID 对象。 此设备的范围必须包含以下 _DSM 定义,该定义指示设备支持哪些 _DSM。

UUID 修订 函数 说明

A7611840-99FE-41ae-A488-35C75926C8EB

0

0

枚举函数

返回:为了表明对上面列出的函数 0 到 3 的支持,枚举函数(函数 0)应返回 0xF。 有关详细信息,请参阅 ACPI 规范的第 9.1.1 部分。


获取风扇跳变点支持函数(函数 1)

硬件告知 OS 在 RPM 方面支持的内容。

UUID 修订 函数 说明

A7611840-99FE-41ae-A488-35C75926C8EB

0

1

获取风扇跳变点支持

参数

Arg0:UUID:A7611840-99FE-41ae-A488- 35C75926C8EB

Arg1:修订版:0

Arg2:函数:1

Arg3:空包


返回:一个整数值,该值包含 RPM 中风扇跳变点支持的粒度。 如果非零,OS 可能选择的跳变点是通知粒度的倍数。 例如,如果粒度为 200,则允许 OSPM 选择 0、200、400、600 等 RPM 的跳变点。 值为 0 表示不支持跳变点。


设置风扇跳变点函数(函数 2)

OS 与硬件沟通下一个通知跳变点;硬件会在发生这种情况时通知 OS。

UUID 修订 函数 说明

A7611840-99FE-41ae-A488-35C75926C8EB

0

2

获取风扇跳变点

参数

Arg0:UUID:A7611840-99FE-41ae-A488- 35C75926C8EB

Arg1:修订版:0

Arg2:函数:2

Arg3:包含上下跳变点的包。 (2 个元素整数值在索引 0 处为下限,在索引 1 处为上限)

OSPM 选择的跳转点是函数 1 中指定跳转点粒度的倍数。 当风扇的实际速度超过或低于跳转点上限/下限时,平台应在风扇设备上发出 Notify(0x80) 命令。 然后,OSPM 将评估 _FST(风扇状态),以确定当前的风扇速度。 如果设置跳转点时风扇速度已超出指定跳转点,则平台应立即发出 Notify(0x80) 命令。

跳转点上限将是粒度的倍数。 跳转点下限将是(粒度的倍数)+ 1(跳转点下限 < 跳转点上限)。 当 RPM 为 0 时,OS 会将跳转点下限设置为 0,将跳转点上限设置为 1。

返回:无。


获取风扇操作范围函数(函数 3)

RPM –> 影响之间的映射。 请注意,只有一个风扇(最接近 SoC)能实现此接口,它必须根据 ACPI 规范的第 9.1.1 部分实现所有 3 个函数和函数 0

UUID 修订 函数 说明

A7611840-99FE-41ae-A488-35C75926C8EB

0

3

获取风扇操作范围

参数

Arg0:UUID:A7611840-99FE-41ae-A488- 35C75926C8EB

Arg1:修订版:0

Arg2:函数:3

Arg3:空包。

返回:包含以下格式的包:

Package () {
	Impact1MaxRPM,		// Integer (DWORD)
	Impact2MaxRPM, 		// Integer (DWORD)
	Impact3MaxRPM, 		// Integer (DWORD)
	MaxRPM				// Integer (DWORD)
}
字段 格式 说明

Impact1MaxRPM

整数 (DWORD)

风扇影响范围 1 的最大 RPM。

Impact2MaxRPM

整数 (DWORD)

风扇影响范围 2 的最大 RPM。 必须 >= Impact1MaxRPM。

Impact3MaxRPM

整数 (DWORD)

风扇影响范围 3 的最大 RPM。 必须 >= Impact2MaxRPM。

MaxRPM

整数 (DWORD)

风扇可以运行的最大 RPM。 必须 >= Impact3MaxRPM。


此表用于派生每个风扇影响级别的 RPM 范围:

影响分数 RPM 下限值 RPM 上限值

1

1

Impact1MaxRPM

2

Impact1MaxRPM + 1

Impact2MaxRPM。

3

Impact2MaxRPM + 1

Impact3MaxRPM

4

Impact3MaxRPM + 1

MaxRPM

如果平台未使用影响范围(例如,如果风扇直接从影响范围 2 转换到影响范围 4),则可以通过将未使用的影响范围的最大 RPM 设置为等于影响范围下限的最大 RPM 来指明这一点。

映射示例

发送到 OS 的值 风扇 RPM 用户体验 RPM 上限

0 – 低

1-4000 RPM (<=25 dBA)

风扇不打开或打开但存在低干扰

Impact1MaxRPM = 4000

1 – 中

4001-5000 RPM (25-30 dBA)

风扇打开,存在中度干扰

Impact2MaxRPM = 5000

2 – 中-高

5001-6000 RPM (30-36 dBA)

风扇打开,存在中-高干扰

Impact3MaxRPM = 6000

3 – 高

6001+ RPM (36+ dBA)

风扇打开,存在高干扰

MaxRPM = 9000


ASL 代码示例

    ...
 
    // _DSM - Device Specific Method
    // Arg0: UUID Unique function identifier
    // Arg1: Integer Revision Level
    // Arg2: Integer Function Index (0 = Return Supported Functions)
    // Arg3: Package Parameters
    Method(_DSM, 0x4, NotSerialized) {
            If(LEqual(Arg0, ToUUID("A7611840-99FE-41ae-A488-35C75926C8EB"))) {
                Switch (ToInteger(Arg2)) {
                    Case(0) {
                        // _DSM functions 0 through 3 are supported
                        Return (Buffer() {0xf})
                    }
                    Case(1) {
                        // Report 200 RPM granularity for trip points
                        Return (\_SB.FAN0.GRAN)
                    }
                    Case(2) {
                        // Save lower RPM trip point
                        Store(DeRefOf(Index(Arg3, 0)), \_SB.FAN0.LRPM)
                        // Save upper RPM trip point
                        Store(DeRefOf(Index(Arg3, 1)), \_SB.FAN0.URPM)
                        // Configure hardware for the trip points, Tell EC to set fan speed trip point.
                        \_SB.FAN0.CRNF()
                        Return (0)
                    }
                    Case(3) {
                        Return (Package(4) { 
                            4000, // 1-4000 RPM is impact score 1
                            5000, // 4001-5000 RPM is impact score 2
                            6000, // 5001-6000 RPM is impact score 3
                            9000})// 6001-9000 RPM is impact score 4
                    }
                    Default {
                        Return(Buffer(One) { 0x00 }) // Guid mismatch
                    }
                }
            }
            Else {
                Return(Buffer(One) { 0x00 }) // Guid mismatch
            }
    }  
 
} // end of FAN0
}

测试和跟踪

请参阅以下步骤,在 Windows 性能分析器 (WPA) 中收集日志并查看:

  1. 设置 ->搜索 Windows -> 高级搜索索引器设置 -> 高级 -> 删除和重新生成索引(重新生成)
  2. wpr -boottrace -addboot AcpiFanNoiseImpact.wprp –filemode
  3. 重新启动系统
  4. 检查设置的索引状态 -> 搜索 Windows(确保设备使用 AC 电源连接)。
  5. 索引完成后,停止跟踪:wpr -boottrace -stopboot AcpiFanNoiseImpact.etl(取消跟踪而不保存:wpr -boottrace –cancel)
  6. 通过 Windows 性能分析器 (WPA) 打开 AcpiFanNoiseImpact.etl。

Indexing Options

AcpiFanNoiseImpact.zip 处下载文件,或者复制以下内容并另存为 AcpiFanNoiseImpact.wprp

<?xml version="1.0" encoding="utf-8"?>
<WindowsPerformanceRecorder Version="1.0" Comments="Test" Company="Microsoft Corporation" Copyright="Microsoft Corporation">
    <Profiles>
        <!-- BufferSizes are in KB in WPRP -->
        <!-- System Collectors -->
        <SystemCollector Id="MySystemCollector" Name="NT Kernel Logger">
            <BufferSize Value="1024" />
            <Buffers Value="100" />
            <StackCaching BucketCount="2048" CacheSize="20480" />
            <FlushThreshold Value="70" />
        </SystemCollector>

        <!-- Event Collectors -->
        <EventCollector Id="MyEventCollector" Name="User Session Logger">
            <BufferSize Value="1024" />
            <Buffers Value="100" />
            <StackCaching BucketCount="2048" CacheSize="20480" />
            <FlushThreshold Value="70" />
        </EventCollector>

        <!-- System Providers for collecting kernel events. -->
        <SystemProvider Id="SP_AcpiFanNoiseImpactTrace">
            <Keywords Operation="Add">
                <Keyword Value="Loader" />
                <Keyword Value="Power" />
                <Keyword Value="ProcessThread" />
            </Keywords>
        </SystemProvider>
        <!-- System Providers for collecting kernel events. -->
        <!---->

        <EventProvider Id="EP_Microsoft-Windows-Kernel-Power" Name="Microsoft-Windows-Kernel-Power" Level="5" NonPagedMemory="true">
            <Keywords>
                <Keyword Value="0x2" />
            </Keywords>
            <CaptureStateOnStart>
                <Keyword Value="0x0" />
            </CaptureStateOnStart>
            <CaptureStateOnSave>
                <Keyword Value="0x0" />
            </CaptureStateOnSave>
        </EventProvider>
        <EventProvider Id="EP_Microsoft-Windows-Kernel-Acpi" Name="Microsoft-Windows-Kernel-Acpi" Level="5">
            <Keywords>
                <Keyword Value="0xffffffff" />
            </Keywords>
            <CaptureStateOnSave>
                <Keyword Value="0xffffffff" />
            </CaptureStateOnSave>
        </EventProvider>
        <EventProvider Id="CustomEventProvider_Microsoft.Windows.SRUM.Telemetry_TraceLogging" Name="7073707A-0587-4E03-B31F-6443EB1ACBCD" Level="5" />
        <EventProvider Id="CustomEventProvider_Microsoft.Windows.Kernel.Acpi_TraceLogging" Name="C42BBFDB-4140-4ada-81DF-2B9A18AC6A7B" Level="5" />
        <EventProvider Id="CustomEventProvider_Microsoft.Windows.Kernel.Power_TraceLogging" Name="63bca7a1-77ec-4ea7-95d0-98d3f0c0ebf7" Level="5" />
        <EventProvider Id="CustomEventProvider_AcpiTraceGuid_WPP" Name="03906A40-CCE8-447F-83F4-E2346215DB84" Level="7" />
        <EventProvider Id="CustomEventProvider_Microsoft.Windows.CentralResourceManager_TraceLogging" Name="8215e965-d26e-548e-af0e-940c1f06f250" Level="5" NonPagedMemory="true">
            <CaptureStateOnSave>
                <Keyword Value="0xFFFFFFFFFFFFFFFF" />
            </CaptureStateOnSave>
        </EventProvider>

        <Profile Id="PowerTrace.Verbose.File" LoggingMode="File" Name="PowerTrace" DetailLevel="Verbose" Description="Power trace logging">
            <Collectors>
                <SystemCollectorId Value="MySystemCollector">
                    <SystemProviderId Value="SP_AcpiFanNoiseImpactTrace" />
                </SystemCollectorId>
                <EventCollectorId Value="MyEventCollector">
                    <EventProviders>
                        <EventProviderId Value="EP_Microsoft-Windows-Kernel-Power" />
                        <EventProviderId Value="EP_Microsoft-Windows-Kernel-Acpi" />
                        <EventProviderId Value="CustomEventProvider_Microsoft.Windows.Kernel.Acpi_TraceLogging" />
                        <EventProviderId Value="CustomEventProvider_AcpiTraceGuid_WPP" />
                        <EventProviderId Value="CustomEventProvider_Microsoft.Windows.Kernel.Power_TraceLogging" />
                        <EventProviderId Value="CustomEventProvider_Microsoft.Windows.SRUM.Telemetry_TraceLogging" />
                        <EventProviderId Value="CustomEventProvider_Microsoft.Windows.CentralResourceManager_TraceLogging" />
                    </EventProviders>
                </EventCollectorId>
            </Collectors>
        </Profile>
    </Profiles>
    <TraceMergeProperties>
        <TraceMergeProperty Id="TraceMerge_Default" Name="TraceMerge_Default" Base="">
            <DeletePreMergedTraceFiles Value="true" />
            <FileCompression Value="true" />
            <CustomEvents>
                <CustomEvent Value="ImageId" />
                <CustomEvent Value="BuildInfo" />
                <CustomEvent Value="VolumeMapping" />
                <CustomEvent Value="EventMetadata" />
                <CustomEvent Value="PerfTrackMetadata" />
                <CustomEvent Value="WinSAT" />
                <CustomEvent Value="NetworkInterface" />
            </CustomEvents>
        </TraceMergeProperty>
    </TraceMergeProperties>
</WindowsPerformanceRecorder>

下图是 WPA 图形示例,显示当风扇声响亮时,搜索索引器退避。

WPA Background Work

有一个级别的风扇将使搜索索引完全退避(最高,应该是影响分数 4),但所有其他级别的风扇应减少活动,而不是暂停。 例如,如果 ACPI 在函数 3 中声明了 Impact3MaxRPM = 4000 RPM(获取风扇操作范围函数),则当风扇 RPM > 4000(4100RPM、4500RPM)时,我们将看到 SearchIndexer.exe,SearchProtocalHost.exe CPU 使用率将暂停。

注意

若要查看 CPU 使用率,可以使用 wpr -start power -filemode 收集运行时使用情况。 使用 wpr -stop fan_noise.etl 停止收集日志。

下图显示了 WPA 图形示例,其中显示 SearchIndexer.exe 和 SearchProtocolHost 暂停

WPA Suspension