NVMe

本部分详细介绍 Microsoft 的内置 NVMe 驱动程序 (StorNVMe) 如何管理功率以及有哪些可用的配置选项。 NVMe 规范允许 NVMe 设备报告最多 32 种功率状态。 每个功率状态都具有以下参数:

  • 最大功耗 (MP)
  • 可运行或不可运行
  • 进入延迟 (ENLAT)
  • 退出延迟 (EXLAT)
  • 相对性能值(相对于其他功率状态)

StorNVMe 将可运行的功率状态(在这些状态下设备可以处理 IO)映射到逻辑性能状态(也称为 P 状态)。 同样,驱动程序将不可运行的功率状态(在这些状态下设备不处理 IO)映射到逻辑空闲电源状态(也称为 F 状态)。 使用 StorNVMe,转换到这些状态在很大程度上取决于整体系统的功率状态。 NVMe 规范定义自主功率状态转换 (APST) 功能。 对于新式待机支持,StorNVMe 不支持启用了 APST 的设备。

运行时设备功率管理

在经过一定的空闲时间后,StorNVMe 可能选择将设备转换为 F 状态。 根据 3 个因素选择 F 状态:

  1. 延迟容差,这是指设备在需要时可以多快地做出响应。 对于 F1,TransitionLatency (ENLAT + EXLAT) 不应大于主要转换延迟容差。 对于 F2 和其他更深层的 F 状态(如果有),其 TransitionLatency 不应大于辅助转换延迟容错。 否则,设备可能无法转换到这些 F 状态,新式待机转换可能会受到影响(例如,引入长时间延迟进入 DRIPS)。
  2. 空闲超时。 这是设备完成上一次 IO 操作的时间量。
  3. 系统功率状态。 如果系统处于主动使用状态,StorNVMe 将更倾向于响应能力。 这意味着将使用不同的延迟容差和超时。

下表显示 StorNVMe 使用的默认空闲超时和延迟容差。 有关如何更改这些设置的说明,请参阅功率配置设置部分。

ACPI 系统功率状态 主空闲超时 主转换延迟容差 次要空闲超时 次要转换延迟容差
S0(工作)- 性能方案 200 毫秒 0 毫秒 (AC)/10 毫秒 (DC) 2000 毫秒 0 毫秒
S0(工作)- 均衡方案 200 毫秒 (AC)/100 毫秒 (DC) 15 毫秒 (AC)/50 毫秒 (DC) 2000 毫秒 (AC)/1000 毫秒 (DC) 100 毫秒
S0(工作)- 节能方案 100 毫秒 100 毫秒 (AC)/200 毫秒 (DC) 1000 毫秒 200 毫秒
S0 低功耗空闲(新式待机) 50 毫秒 500 毫秒 空值 空值

空闲超时过期后,驱动程序将遍历其内部功率状态表,并选择 ENLAT+EXLAT 小于或等于当前转换延迟容差的最深功率状态。

例如,假设 NVMe 设备处于以下功率状态,并且已发生空闲超时:

电源状态 进入延迟 (ENLAT) 退出延迟 (EXLAT)
PS0 5 微秒 5 微秒
PS1 10 毫秒 300 微秒
PS2 50 毫秒 10 毫秒

系统处于直流电源而不处于新式待机状态时,StorNVMe 将选择 PS1,因为这是 (ENLAT+EXLAT) <= 50 毫秒的最深功率状态。 同样,当系统进入新式待机状态时,StorNVMe 将选择 PS2,因为它是 (ENLAT+EXLAT) <= 500 毫秒的最深功率状态。

新式待机和 DRIPS

为完全支持新式待机,StorNVMe 会根据硬件平台提供的提示将设备转换为适当的低功耗状态。 “空闲”状态在 F 状态(深度低于 F0)到 D3 Cold 之间有所不同。 在新式待机状态下,某些平台需要 D3 Cold。 这取决于 SoC,请咨询芯片供应商获取详细信息。 可以按此处所述启用对新式待机系统上存储设备的 D3 支持。

设备应支持具有短恢复延迟的 RTD3,以帮助新式待机系统满足 1 秒的系统恢复延迟要求。 RTD3 恢复延迟 (RTD3R) 是指来自 D3cold 的恢复延迟,建议报告 ≤ 100 毫秒的非零值。 RTD3R 在 NVMe 规范的 8.4.4 部分中进行了介绍。

功率配置设置

Windows 10 支持以下 NVMe 功率设置来调整能效。

主 NVMe 空闲超时

使用以下功率配置设置可以更改 StorNVMe 使用的主设备空闲超时。

Power Setting GUID: d639518a-e56d-4345-8af2-b9f32fb26109  (Primary NVMe Idle Timeout)
      Minimum Possible Setting: 0x00000000
      Maximum Possible Setting: 0x0000ea60
      Possible Settings increment: 0x00000001
      Possible Settings units: milliseconds

使用以下功率配置设置可以更改 StorNVMe 在计算空闲状态时使用的主转换延迟容差值。 这是在空闲超时过期时,与 ENLAT 和 EXLAT 值的总和进行比较的值。 此值越大,选择较深功率状态的可能性就越大。

Power Setting GUID: fc95af4d-40e7-4b6d-835a-56d131dbc80e  (Primary NVMe Power State Transition Latency Tolerance)
      Minimum Possible Setting: 0x00000000
      Maximum Possible Setting: 0x0000ea60
      Possible Settings increment: 0x00000001
      Possible Settings units: milliseconds

次要 NVMe 空闲超时

使用以下功率配置设置可以更改 StorNVMe 使用的次要设备空闲超时。

Power Setting GUID: d3d55efd-c1ff-424e-9dc3-441be7833010  (Secondary NVMe Idle Timeout)
      Minimum Possible Setting: 0x00000000
      Maximum Possible Setting: 0x0000ea60
      Possible Settings increment: 0x00000001
      Possible Settings units: milliseconds

使用以下功率配置设置可以更改 StorNVMe 在计算空闲状态时使用的次要转换延迟容差值。 这是在空闲超时过期时,与 ENLAT 和 EXLAT 值的总和进行比较的值。 此值越大,选择较深功率状态的可能性就越大。

Power Setting GUID: dbc9e238-6de9-49e3-92cd-8c2b4946b472  (Secondary NVMe Power State Transition Latency Tolerance)
      Minimum Possible Setting: 0x00000000
      Maximum Possible Setting: 0x0000ea60
      Possible Settings increment: 0x00000001
      Possible Settings units: milliseconds

若要更改给定功率方案的值,请使用:

powercfg [-setacvalueindex | -setdcvalueindex] <scheme> sub_disk <Power Setting GUID> <milliseconds>

不要忘记使用以下方法来应用值:powercfg –setactive <scheme>

PCIe ASPM 和 L1 Sub-state

取决于平台,你可能会注意到 NVMe 设备在直流电源供电(而不是交流电源供电)时可以进入 L1 子状态。 在这种情况下,你可能需要更改 PCIe ASPM 功率配置设置,使其在交流电源供电(除直流电源供电外)时获得最佳节能效果。

Power Setting GUID: ee12f906-d277-404b-b6da-e5fa1a576df5  (Link State Power Management)
      GUID Alias: ASPM
      Possible Setting Index: 000
      Possible Setting Friendly Name: Off
      Possible Setting Index: 001
      Possible Setting Friendly Name: Moderate power savings
      Possible Setting Index: 002
      Possible Setting Friendly Name: Maximum power savings

若要更改值,请将:

powercfg -setacvalueindex <scheme> sub_pciexpress aspm <value>

与上方的索引 002 配合使用以获得最佳节能效果。 不要忘记使用以下方法来应用值:powercfg –setactive <scheme>

主动功率管理

主动功率管理涉及“P 状态”(也称为性能或“perf”状态),主要用于热控制。 StorNVMe 使用每个可运行功率状态报告的最大功率值,将设备的可运行功率状态映射到逻辑 P 状态。 设备处于活动状态(即具有未完成的 IO)时,StorNVMe 会通过 P 状态转换将设备转换为其可运行功率状态之一。

在 Windows 10开发期间,有一组有限的 NVMe 设备实现了多个可运行功率状态。 根据我们的功率和性能测量,我们发现使用除最高运行功率状态之外的任何状态都没有显著的好处。 因此,使用默认配置时,只会看到使用最高运行功率状态。

所选择的运行功率状态取决于当前“最大运行功率”提示。 此提示可以有 3 种不同的来源:

  • 来自 Windows 热框架的被动冷却回调。
  • 最大功率级别功率配置设置值的变化。 (这可能是系统电源方案或 AC/DC 电源中的更改触发的。)
  • IOCTL_STORAGE_DEVICE_POWER_CAP 请求。 这些来源中的最低最大值是有效的最大运行功率值。 下面讨论了其中每个来源的机制。

一般情况下,StorNVMe 将选择小于或等于有效最大运行功率值的最高运行功率状态。

例如,假设 NVMe 设备具有以下功率状态:

电源状态 最大功率 可运行?
PS0 9W
PS1 6W
PS2 4W

这些来源中的最低最大值是有效的最大运行功率值。 下面讨论了其中每个来源的机制。

一般情况下,StorNVMe 将选择小于或等于有效最大运行功率值的最高运行功率状态。

默认情况下,没有最大功率级别,因此 StorNVMe 将始终选择 PS0。 这等效于 100%。

如果 Windows 热框架调用值为 50% 的被动冷却回调,则会导致绝对功率值为 (50% * (9W – 4W)) + 4W = 6W。 然后,StorNVMe 将确保设备在活动状态时始终处于 PS1 状态,因为该状态的最大功率值为 6W。

随后,某些用户模式进程会向磁盘发送一个值为 5W 的 IOCTL_STORAGE_DEVICE_POWER_CAP 请求。 StorNVMe 现在将选择 PS2,因为它是最高运行功率状态,其最大功率值 (4W) 小于最大运行功率要求 5W。

如果给定的最大运行功率要求小于最低运行功率状态的最大功率值,则只需选择最低运行功率状态。 在我们的示例中,如果给定的最大运行功率要求为 3W,则 StorNVMe 会选择 PS2,因为它没有最大功率值为 3W 或更低的运行功率状态。

如果之后最大运行功率要求更改为 9W,则当设备处于活动状态时,StorNVMe 将重新选择 PS0。

例如,假设 NVMe 设备具有以下功率状态:

Windows 热框架被动冷却回调

StorNVMe(通过 Storport)向 Windows 热框架注册热冷却接口,使系统可以通过该框架限制 NVMe 设备。 这种方法的细节超出了本文档讨论的范围,但一般来说,平台通过 ACPI 指定热区和阈值,然后 Windows 热框架使用这些信息通过对设备的驱动程序进行回调来限制设备。

最大运行功率级别功率配置设置

以下功率配置设置可用于更改不同系统功率方案和 AC/DC 电源的最大运行功率级别。

Power Setting GUID: 51dea550-bb38-4bc4-991b-eacf37be5ec8  (Maximum Power Level)
      GUID Alias: DISKMAXPOWER
      Minimum Possible Setting: 0x00000000
      Maximum Possible Setting: 0x00000064
      Possible Settings increment: 0x00000001
      Possible Settings units: %

若要更改给定功率方案的值,请使用:

powercfg [-setacvalueindex | -setdcvalueindex] <scheme> sub_disk 51dea550-bb38-4bc4-991b-eacf37be5ec8 <value>

不要忘记使用以下方法来应用值:powercfg –setactive <scheme>

IOCTL_STORAGE_DEVICE_POWER_CAP

可以将此 IOCTL 发送到存储设备,以更改最大运行功率级别。 有关详细信息,请参阅输入/输出缓冲区的文档 STORAGE_DEVICE_POWER_CAP。

关机/休眠

系统处于关机或休眠状态时,StorNVMe 会将设备的“关闭通知”(CC.SHN) 字段设置为 1。 然后,StorNVMe 会等待设备报告指示其已就绪的 RTD3 进入延迟(方法是将关机状态 (CSTS.SHST) 字段更新为 2)。 如果未报告任何进入延迟值,则 StorNVMe 将使用默认值 5 秒。 在这种情况下,如果设备所需的时间超过 5 秒,则系统将继续执行关闭或休眠过程,而不会进一步检查 NVMe 设备。 OEM 应仅使用报告新式待机系统的 RTD3 进入和退出值的设备。