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

13

目前我已经找到了以下信息:

  • SSE和SSE2在Windows 8及更高版本(当然也适用于任何64位操作系统)是必须的。
  • AVX仅支持Windows 7 SP1或更高版本。

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

需要澄清的是:我需要确定如果我使用SSE/AVX指令集中的一种,我的程序将在哪些操作系统上运行。


我不认为这是一个适合SU的问题,我怀疑即使是最厉害的超级用户也不会编写汇编代码。我会重新措辞问题,以便更清楚地表明我正在尝试利用程序中的操作码。 - Alexey
2
我不明白为什么这个问题只是“关于一般计算软件”。它包含“Windows”并不意味着它在这里是离题的。这是一个关于程序员视角下平台的问题,对于那些编写SSE/AVX等代码的人来说显然很重要。 - stgatilov
1个回答

17

引入新的架构状态的扩展需要特殊的操作系统支持,因为操作系统必须在上下文切换时保存/恢复更多的数据。因此,从操作系统的角度来看,如果操作系统支持SSE,它不需要额外做任何事情就可以让用户空间代码运行SSSE3指令。

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

  • SSE引入了xmm寄存器(以及MXCSR用于舍入模式和FP异常状态)。
  • AVX引入了ymm(其下半部分是旧的xmm寄存器)。
  • AVX512引入了zmm(扩展了x/ymm寄存器),并且在64位模式下向量寄存器的数量翻倍:zmm0-zmm31。只有使用AVX-512编码的向量指令(EVEX前缀)才能访问x/y/zmm16..31,因此有趣的是可以在不需要vzeroupper的情况下使用它们,并且不受其影响
    k0..k7 64位掩码寄存器(或在Xeon Phi中没有AVX-512BW时为16位)也是AVX-512中的新功能。

您可以使用CPUID指令来检查CPU是否支持SSE或AVX。

当在一个多任务操作系统上使用新扩展且该操作系统在上下文切换时不保存/恢复新的体系结构状态时,为了防止静默数据损坏,如果操作系统没有在控制寄存器中设置操作系统支持位,则SSE指令会出现非法指令故障。因此,在不知道保存/恢复该扩展所需状态的操作系统上,“矢量扩展”将“无法工作”。


对于SSE而言,可能没有任何干净的与操作系统无关的方法来检测操作系统是否已经承诺通过设置CR4.OSFXSRCR4.OSXMMEXCPT等位来保存/恢复SSE状态以进行上下文切换,因为即使读取控制寄存器也是特权级操作,并且没有CPUID位反映该设置。SSE支持如此普及,以至于您必须使用一个非常古老的版本(或自制)操作系统才会出现此问题。
对于AVX,我们不需要操作系统支持来检测AVX是否可用(由硬件支持并由操作系统启用):用户空间可以运行xgetbv并检查已启用的功能标志,以查看操作系统是否已启用AVX指令以便无故障运行。

来自Intel's intro to AVX

  • 使用CPUID.1:ECX.OSXSAVE位27 = 1验证操作系统是否支持XGETBV。
  • 同时,验证CPUID.1:ECX位28 = 1(支持Intel AVX)和/或位25 = 1(支持AES)... (以及其他位用于FMA、AES和PCLMULQDQ)
  • 发出XGETBV,并验证位于位1和2的功能启用掩码为11b(由操作系统启用XMM状态和YMM状态)。
使用操作系统提供的函数来检测操作系统支持情况可能比使用内联汇编或特性检测库更容易。例如,Win7SP1引入了GetEnabledXStateFeatures函数,同时支持AVX CPU。(很难或者不可能在没有SSE的CPU上找到运行Win7SP1的情况,因此对于SSE,您可以仅检查CPUID和操作系统版本。)
这也被理解为承诺操作系统的上下文切换将正确保存/恢复完整状态,尽管当然有缺陷、恶意或奇特的操作系统(也许是协作式多任务?)可能会有所不同。对于包括Windows在内的主流操作系统,这意味着YMM寄存器将像您预期的那样保留其值。
同样适用于AVX512:您可以检查CPUID功能位以获取指令集,并检查操作系统是否承诺通过启用XSETBV中的正确位来管理上下文切换时的新架构状态。(因此,您应该使用XGETBV进行检查)。检查XGETBV结果AND 0xE6等于0xE6。

这意味着我不能在2013年之前发布的操作系统下运行的程序中使用AVX512扩展,因为那时它才被宣布。你知道哪些Windows版本将接收更新以正确处理zmm寄存器吗? - Alexey
4
实际上,你应该使用IsProcessorFeaturePresentGetEnabledXStateFeatures,因为它们可以告诉你CPU功能是否存在,以及操作系统是否支持它们。如果在CPU中检测到(例如)AVX支持,并且使用AVX指令,但发现每次上下文切换时AVX状态都会被破坏,这将是不好的,因为操作系统没有AVX上下文切换支持。 - Raymond Chen
1
@RaymondChen 其实情况并没有你想象的那么糟糕。处理器会强制执行它。如果程序在未设置XSAVE位时尝试执行AVX指令,处理器将发出非法指令异常。为了向后兼容,默认情况下未设置XSAVE位。一旦操作系统设置了它,它就已经“接受了合同”,即它将在上下文切换时保留ymm状态。然后处理器将允许您执行AVX指令。 - Mysticial
1
替换完整功能查询的函数是IsProcessorFeaturePresent。它存在于旧操作系统中(至少从WinNT4 / Win98开始就有了)。但它可能不支持在旧操作系统中检测某些功能;例如,在Windows 2000中,它不支持检测SSE2,而如果CPU中存在SSE2,则可以使用它。 - Alex Guteniev
1
AVX/AVX2标志的IsProcessorFeaturePresent未经记录,因此不确定它们需要哪个操作系统。这使得__cpuid+_xgetvb成为更有吸引力的解决方案。(还不想在代码的其他可能可移植部分中添加API调用) - Alex Guteniev
显示剩余13条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接