为什么 SSE 指令保留 YMM 寄存器的高 128 位?
Why do SSE instructions preserve the upper 128-bit of the YMM registers?
似乎 recurring problem 许多 Intel 处理器(直到 Skylake,除非我错了)在将 AVX-256 指令与 SSE 指令混合时表现出较差的性能。
根据Intel's documentation,这是由于SSE指令被定义为保留YMM寄存器的高128位,所以为了能够通过不使用YMM寄存器的高128位来省电AVX 数据路径,CPU 在执行 SSE 代码时将这些位存储起来,并在输入 AVX 代码时重新加载它们,存储和加载都很昂贵。
但是,我找不到明显的理由或解释为什么 SSE 指令需要保留那些高 128 位。相应的 128 位 VEX 指令(使用它可以避免性能损失)通过始终清除 YMM 寄存器的高 128 位而不是保留它们来工作。在我看来,当英特尔定义 AVX 架构时,包括将 XMM 寄存器扩展到 YMM 寄存器时,他们本可以简单地定义 SSE 指令也将清除高 128 位。显然,由于 YMM 寄存器是新的,因此可能没有依赖于保留这些位的 SSE 指令的遗留代码,而且在我看来,英特尔很容易预见到这一点。
那么,Intel定义SSE指令保留YMM寄存器高128位的原因是什么?它有用吗?
为了移动外部资源in-site,我从the link Michael provided in the comments中提取了相关段落。
所有功劳归于他。
link 指向 Agner Fog 在英特尔论坛上提出的一个非常相似的问题。
[Fog in respone to Intel's answer] If I understand you right, you decided that it is necessary to have two versions of all 128-bit instructions in order to avoid
destroying the upper part of the YMM registers in case an interrupt calls a device driver using legacy XMM instructions.
英特尔担心,通过使旧版 SSE 指令将 XMM 寄存器的上部归零,ISR 现在会突然
影响新的 YMM 寄存器。
如果不支持保存新的 YMM 上下文,这将使 AVX 在任何情况下都无法使用
情况。
然而,Fog 并不完全满意,并指出通过简单地使用 AVX 感知编译器重新编译驱动程序(以便 VEX
使用指令)会导致相同的结果。
英特尔回答说,他们的目标是避免强迫现有软件成为
重写。
There is no way we could compel the industry to rewrite/fix all of their existing drivers (for example to use XSAVE) and no way to guarantee they would have done so successfully. Consider for example the pain the industry is still going through on the transition from 32 to 64-bit operating systems! The feedback we have from OS vendors also precluded adding overhead to the ISR servicing to add the state management overhead on every interrupt. We didn't want to inflict either of these costs on portions of the industry that don't even typically use wide vectors.
通过有两个版本的指令,可以在驱动程序中实现对 AVX 的支持,就像 FPU/SSE:
The example given is similar to the current scenario where a ring-0 driver (ISR) vendor attempts to use floating-point state, or accidentally links it in some library, in OSs that do not automatically manage that context at Ring-0. This is a well known source of bugs and I can suggest only the following:
On those OSs, driver developers are discouraged from using floating-point or AVX
Driver developers should be encouraged to disable hardware features during driver validation (i.e. AVX state can be disabled by drivers in Ring-0 through XSETBV()
背景:很早就决定让 KeSaveFloatingPointState 在 Windows x64 上不执行任何操作,并允许在没有额外 save/restore 调用的情况下使用 XMM 寄存器,即使在驱动程序中也是如此。显然,这些驱动程序不会知道 AVX 或 YMM 寄存器。
似乎 recurring problem 许多 Intel 处理器(直到 Skylake,除非我错了)在将 AVX-256 指令与 SSE 指令混合时表现出较差的性能。
根据Intel's documentation,这是由于SSE指令被定义为保留YMM寄存器的高128位,所以为了能够通过不使用YMM寄存器的高128位来省电AVX 数据路径,CPU 在执行 SSE 代码时将这些位存储起来,并在输入 AVX 代码时重新加载它们,存储和加载都很昂贵。
但是,我找不到明显的理由或解释为什么 SSE 指令需要保留那些高 128 位。相应的 128 位 VEX 指令(使用它可以避免性能损失)通过始终清除 YMM 寄存器的高 128 位而不是保留它们来工作。在我看来,当英特尔定义 AVX 架构时,包括将 XMM 寄存器扩展到 YMM 寄存器时,他们本可以简单地定义 SSE 指令也将清除高 128 位。显然,由于 YMM 寄存器是新的,因此可能没有依赖于保留这些位的 SSE 指令的遗留代码,而且在我看来,英特尔很容易预见到这一点。
那么,Intel定义SSE指令保留YMM寄存器高128位的原因是什么?它有用吗?
为了移动外部资源in-site,我从the link Michael provided in the comments中提取了相关段落。
所有功劳归于他。
link 指向 Agner Fog 在英特尔论坛上提出的一个非常相似的问题。
[Fog in respone to Intel's answer] If I understand you right, you decided that it is necessary to have two versions of all 128-bit instructions in order to avoid destroying the upper part of the YMM registers in case an interrupt calls a device driver using legacy XMM instructions.
英特尔担心,通过使旧版 SSE 指令将 XMM 寄存器的上部归零,ISR 现在会突然
影响新的 YMM 寄存器。
如果不支持保存新的 YMM 上下文,这将使 AVX 在任何情况下都无法使用
情况。
然而,Fog 并不完全满意,并指出通过简单地使用 AVX 感知编译器重新编译驱动程序(以便 VEX 使用指令)会导致相同的结果。
英特尔回答说,他们的目标是避免强迫现有软件成为 重写。
There is no way we could compel the industry to rewrite/fix all of their existing drivers (for example to use XSAVE) and no way to guarantee they would have done so successfully. Consider for example the pain the industry is still going through on the transition from 32 to 64-bit operating systems! The feedback we have from OS vendors also precluded adding overhead to the ISR servicing to add the state management overhead on every interrupt. We didn't want to inflict either of these costs on portions of the industry that don't even typically use wide vectors.
通过有两个版本的指令,可以在驱动程序中实现对 AVX 的支持,就像 FPU/SSE:
The example given is similar to the current scenario where a ring-0 driver (ISR) vendor attempts to use floating-point state, or accidentally links it in some library, in OSs that do not automatically manage that context at Ring-0. This is a well known source of bugs and I can suggest only the following:
On those OSs, driver developers are discouraged from using floating-point or AVX
Driver developers should be encouraged to disable hardware features during driver validation (i.e. AVX state can be disabled by drivers in Ring-0 through XSETBV()
背景:很早就决定让 KeSaveFloatingPointState 在 Windows x64 上不执行任何操作,并允许在没有额外 save/restore 调用的情况下使用 XMM 寄存器,即使在驱动程序中也是如此。显然,这些驱动程序不会知道 AVX 或 YMM 寄存器。