Assembly 将SSE与AVX128混合以获得更短的指令?

Assembly 将SSE与AVX128混合以获得更短的指令?,assembly,x86,sse,avx,micro-optimization,Assembly,X86,Sse,Avx,Micro Optimization,从我所能收集到的所有信息来看,混合使用SSE和128位(E)VEX编码指令不会造成性能损失。这表明将两者混合使用应该是好的。当SSE指令通常比VEX等效指令短1字节时,这可能是有益的 然而,我从未见过任何人或任何编译器这样做。例如,在Intel的AVX(128位)MD5实现中,可以替换为movaps(或者可以替换为较短的shufps,因为dest和src1寄存器相同)。 避免使用SSE有什么特别的原因吗,或者我遗漏了什么吗?你说得对,如果YMM Upper在vzeroupper中已知为零,那么混

从我所能收集到的所有信息来看,混合使用SSE和128位(E)VEX编码指令不会造成性能损失。这表明将两者混合使用应该是好的。当SSE指令通常比VEX等效指令短1字节时,这可能是有益的

然而,我从未见过任何人或任何编译器这样做。例如,在Intel的AVX(128位)MD5实现中,可以替换为
movaps
(或者可以替换为较短的
shufps
,因为dest和src1寄存器相同)。

避免使用SSE有什么特别的原因吗,或者我遗漏了什么吗?

你说得对,如果YMM Upper在
vzeroupper
中已知为零,那么混合使用AVX128和SSE不会有任何惩罚,而且在节省代码大小时不这样做是遗漏的优化

还要注意的是,如果不需要REX前缀,它只会节省代码大小。对于SSE1,2字节VEX相当于REX+0F。编译器确实尝试使用低寄存器来避免REX前缀,但我认为他们没有考虑在每条指令中使用哪些寄存器组合来最小化REX前缀总量。(或者如果他们真的这么做,他们就不擅长)。人类可以花时间做这样的计划

它在大多数情况下都很小,只是偶尔有一个字节的代码大小。这通常是一件好事,可以帮助前端。(或为英特尔CPU上超过
pblendvps xmm、xmm、xmm、xmm
的设备保存uop(对于pd和pblendvb相同),前提是您可以安排使用它而无需另一个
movaps

如果你弄错了,那么缺点就是SSE/AVX过渡惩罚(在Haswell和Ice Lake上),或者错误地依赖Skylake。IDK如果Zen2做了这样的事情;Zen1将256位操作拆分为2个UOP,不关心vzeroupper


为了使编译器能够安全地执行此操作,他们必须跟踪更多内容,以确保在YMM寄存器的上半部分脏的情况下,不会在函数中运行SSE指令。编译器没有将AVX code gen限制为仅128位指令的选项,因此它们必须开始跟踪可能会弄脏YMM上半部分的执行路径

但是,我认为他们必须在整个函数的基础上这样做,才能知道在
ret
之前何时使用
vzeropper
(在不按值接受或返回
\uuuum256/I/d
的函数中,这意味着调用者已经在使用宽向量)

但是不需要
vzeroupper
movaps
是否是性能安全的是两码事,因此以类似的方式进行跟踪是另外一件事。在每种情况下都可以安全地避免使用VEX前缀

尽管如此,在某些情况下,很容易证明它是安全的。如果编译器使用一个保守的算法,当分支可能有或可能没有脏的上限时,该算法会错过一些优化,在这种情况下,总是使用VEX,并且总是使用
vzeropper