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