似乎是recurring problem许多英特尔处理器(直到Skylake,除非我错了)在将AVX-256指令与SSE指令混合时表现不佳。
根据Intel's documentation,这是由SSE指令定义为保留YMM寄存器的高128位引起的,因此为了能够通过不使用AVX数据路径的高128位来节省功耗,CPU在执行SSE代码时将这些位存储起来,并在输入AVX代码时重新加载它们,存储和加载都很昂贵。
但是,我找不到明显的理由或解释为什么SSE指令需要保留那些高128位。相应的128位VEX指令(使用它避免了性能损失)通过始终清除YMM寄存器的高128位而不是保留它们来工作。在我看来,当英特尔定义AVX架构,包括将XMM寄存器扩展到YMM寄存器时,他们可以简单地定义SSE指令也将清除高128位。显然,由于YMM寄存器是新的,可能没有遗留代码依赖于保留这些位的SSE指令,而且在我看来,英特尔可以很容易地看到这一点。
那么,英特尔定义SSE指令以保留YMM寄存器的高128位的原因是什么?它有用吗?
答案 0 :(得分:11)
为了在现场移动外部资源,我从the link Michael provided in the comments中提取了相关段落。
所有信用都归他所有。
该链接指出了Agner Fog在英特尔论坛上提出的一个非常类似的问题。
[对英特尔答案的反思] 如果我理解你的话,你认为必须有两个版本的所有128位指令才能避免 如果中断使用传统XMM指令调用设备驱动程序,则销毁YMM寄存器的上半部分。
英特尔担心,通过将传统的SSE指令归零XMM寄存器的上半部分,ISR现在会突然出现 影响新的YMM寄存器 如果不支持保存新的YMM上下文,这将使AVX在任何情况下都无法使用 情况。
然而,Fog并不完全满意,并指出只需使用AVX感知编译器重新编译驱动程序(以便VEX 使用说明会产生相同的结果。
英特尔回复说,他们的目标是避免强制使用现有软件 重写。
我们无法强迫行业重写/修复所有现有的驱动程序(例如使用XSAVE),也无法保证他们能够成功完成。例如,考虑到从32位到64位操作系统的过渡行业仍在经历的痛苦!我们从OS供应商那里得到的反馈也阻止了为ISR服务增加开销,以便在每次中断时添加状态管理开销。我们并不想在行业中甚至通常不使用宽矢量的部分成本中承担这些成本。
通过两个版本的指令,可以像FPU / SSE一样实现对驱动程序中AVX的支持:
给出的示例类似于当前情况,其中ring-0驱动程序(ISR)供应商尝试使用浮点状态,或意外地将其链接到某些库中,而不是在Ring中自动管理该上下文的操作系统中0。这是一个众所周知的错误来源,我只能建议如下:
在这些操作系统上,不鼓励驱动程序开发人员使用浮点或AVX
- 中的驱动程序可以禁用AVX状态
应鼓励驱动程序开发人员在驱动程序验证期间禁用硬件功能(即,Ring-0到XSETBV()
答案 1 :(得分:1)
背景:早期决定使KeSaveFloatingPointState在Windows x64上不执行任何操作,并允许使用XMM寄存器,即使在驱动程序中也无需额外的保存/恢复调用。显然,这些驱动程序不会知道AVX或YMM寄存器。