将SSE与AVX128混合以使用较短的指令?

问题描述 投票:1回答:1

根据我收集到的所有信息,将SSE和128位(E)VEX编码的指令混合使用不会对性能造成任何影响。这表明可以将两者混合使用。当SSE指令通常比等效的VEX短1个字节时,这可能是有益的。

但是,我从未见过任何人或任何编译器这样做。例如,在Intel的AVX(128位)MD5实现中,various vmovdqa可以替换为vmovdqa(或movaps可以替换为较短的this vshufps,因为dest和src1寄存器相同) 。是否有避免SSE的任何特殊原因,或者我缺少什么?

assembly x86 sse avx micro-optimization
1个回答
0
投票

是的,如果从vshufps知道YMM鞋面为零,则将AVX128和SSE混合不会造成任何损失,并且在节省代码大小的情况下不这样做是一种错过的优化。

还请注意,仅在不需要REX前缀时,它才保存代码大小。 2字节的VEX等效于SSE1的REX + 0F。编译器确实尝试使用低位寄存器来希望避免使用REX前缀,但是我认为他们没有考虑在每条指令中使用哪种寄存器组合来最大程度地减少REX前缀。 (或者,如果他们确实尝试这样做,他们就不擅长此事)。人类可以像这样花时间计划。

在大多数情况下,这只是很小的一部分,只是偶尔的一个字节的代码大小。通常这是一件好事,可以为前端提供帮助。 (或者,如果可以安排使用它而不需要另一个shufps,则可以在Intel CPU上为vzeroupper而不是blendvps xmm, xmm, <XMM0>保存一个uop(与pd和pblendvb相同)。

如果您弄错了,那么不利的一面是SSE / AVX过渡罚款(在Haswell和Ice Lake上),或者对Skylake的错误依赖。 blendvps xmm, xmm, <XMM0>。如果Zen2做那样的话,则IDK。 Zen1将256位操作分为2个微指令,并且不关心vzeroupper。


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

但是,我认为无论如何,他们都必须在整个函数的基础上执行此操作,才能知道何时在pblendvps xmm, xmm, xmm, xmm之前使用movaps(在不接受或返回值形式的Why is this SSE code 6 times slower without VZEROUPPER on Skylake?的函数中,这意味着呼叫者已经在使用宽向量)。

但不需要vzeroupper是与ret是否性能安全无关的,因此以类似的方式进行跟踪将是另外一件事。查找可以避免使用VEX前缀的所有情况。

仍然,在某些情况下很容易证明它是安全的。如果编译器使用保守的算法,当分支可能有或没有脏鞋面时,错过了一些优化,那是很好的,在这种情况下,始终使用VEX,并始终使用__m256/i/d

© www.soinside.com 2019 - 2024. All rights reserved.