Windows support/require 哪些版本的 CPU 多媒体扩展? (如何检查 SSE 或 AVX 是否完全可用?)

Which versions of Windows support/require which CPU multimedia extensions? (How to check if SSE or AVX are fully usable?)

到目前为止,我设法发现:

在 Windows 上使用 SSE3、SSSE3、SSE4.1、SSE 4.2、AVX2 和 AVX-512 是否有任何注意事项?

一些说明:如果我使用来自 SSE/AVX 组之一的指令,我需要它来确定我的程序 运行 将在 OS 上运行什么。

引入新架构状态的扩展需要特殊的 OS 支持,因为 OS 必须 save/restore 在上下文切换时恢复更多数据。因此,从 OSes 的角度来看,如果 OS 支持 SSE,那么让用户 space 代码 运行 SSSE3 指令不需要做任何额外的事情。

SSE、AVX 和 AVX512 是引入新架构状态的扩展。

  • SSE 引入了 xmm regs(和 MXCSR 用于舍入模式和 FP 异常状态)
  • AVX 引入了 ymm(下半部分是旧的 xmm 规则)。
  • AVX512 引入了 zmm(扩展了 x/ymm regs),并且还在 64 位模式下将矢量 regs 的数量增加了一倍:zmm0-zmm31。 x/y/zmm16..31 只能通过矢量指令的 AVX-512 编码(EVEX 前缀)访问,因此有趣的是可以在没有 , and .
    的情况下使用 k0..k7 64 位掩码寄存器(或 Xeon Phi 中没有 AVX-512BW 的 16 位)在 AVX-512 中也是新增的。

您使用 CPUID 指令以通常的方式检查 CPU 对 SSE 或 AVX 的支持。

为了防止在多任务 OS 上使用新扩展时静默数据损坏,而 save/restore 上下文切换时没有新的体系结构状态,如果OS 没有 。因此矢量扩展在 OS 不知道 saving/restoring 该扩展的必要状态的 es 上“不起作用”。


对于 SSE,可能没有任何干净的 OS-独立方式 来检测 OS 已承诺 save/restore SSE通过设置 CR4.OSFXSRCR4.OSXMMEXCPT 等位来切换上下文状态,因为 even reading a control register is privileged,并且没有反映设置的 CPUID 位。 SSE 支持如此广泛,以至于您必须使用非常古老的版本(或自制软件)OS 才会成为问题。


对于 AVX,我们不需要 OS 支持来检测 AVX 是否可用(由硬件支持并由 OS 启用): User-space 可以 运行 xgetbv 并检查启用的功能标志以查看 OS 是否已启用 AVX 指令 运行 而不会出错。

来自 Intel's intro to AVX:

  • Verify that the operating system supports XGETBV using CPUID.1:ECX.OSXSAVE bit 27 = 1.
  • At the same time, verify that CPUID.1:ECX bit 28=1 (Intel AVX supported) and/or bit 25=1 (AES supported) ... (and other bits for FMA, AES, and PCLMULQDQ)
  • Issue XGETBV, and verify that the feature-enabled mask at bits 1 and 2 are 11b (XMM state and YMM state enabled by the operating system).

调用 OS 提供的函数来检测 OS 支持可能更容易,而不是使用内联 asm 或功能检测库来完成所有这些。例如,Win7SP1 引入了 GetEnabledXStateFeatures 以及对 AVX CPU 的支持。 (在没有 SSE 的 CPU 上不太可能或不可能找到 Win7SP1 运行ning,因此对于 SSE,您只需检查 CPUID 和 OS 版本即可。)

这也被理解为 OS 的上下文切换将正确 save/restore 完整状态的承诺,尽管当然是错误的、恶意的或深奥的 OS (也许是协作式多任务处理?)可能会有所不同。对于包括 Windows 在内的主流 OSes,这确实意味着 YMM 寄存器将像您期望的那样保持其值。


AVX512也是如此:可以查看指令集的CPUID特征位,检查 OS 是否已承诺通过在 XSETBV 中启用正确的位来管理上下文切换时的新架构状态。 (所以你应该检查 XGETBV)。检查 XGETBV 结果并且 0xE6 等于 0xE6。