AVX equivalent for _mm_movelh_ps

AVX equivalent for _mm_movelh_ps

本文关键字:movelh ps mm AVX for equivalent      更新时间:2023-10-16

由于没有AVX版本的_mm_movelh_ps我通常使用AVX寄存器的_mm256_shuffle_ps(a, b, 0x44)作为替代品。但是,我记得在其他问题中读到,如果可能的话,应该首选没有控制整数(如_mm256_unpacklo_ps_mm_movelh_ps)的摆动指令(出于某种原因我不知道)。昨天,我突然想到,另一种选择可能是使用以下方法:

_mm256_castpd_ps(_mm256_unpacklo_pd(_mm256_castps_pd(a), _mm256_castps_pd(b)));

既然强制转换应该是无操作的,这是否比在性能方面使用_mm256_shuffle_ps更好\等于\更差?

此外,如果真的是这样,如果有人能用简单的话解释(我对汇编和微架构的理解非常有限)为什么人们应该更喜欢没有控制整数的指令,那就太好了。

提前致谢

附加说明:Clang 实际上优化了洗牌以vunpcklpd:https://godbolt.org/z/9XFP8D 所以看来我的想法还不错。但是,GCC 和 ICC 会创建随机指令。

避免立即节省 1 字节的机器代码大小;仅此而已。 出于性能考虑,它位于列表的底部,但由于这个原因,所有其他相同的洗牌(如具有隐式"控制"的_mm256_unpacklo_pd)都比直接控制字节略好。

(但是在另一个向量中获取控制操作数(如vpermilps可以或vpermd要求)通常更糟,除非你在长时间运行的循环中有一些奇怪的前端瓶颈,并且可以在循环之外加载随机控件。 不是很合理,在这一点上,您必须在 asm 中手动编写才能非常关心代码大小/对齐方式;在C++,这仍然不是你可以直接控制的东西。

既然强制转换应该是无操作的,这是否比在性能方面使用_mm256_shuffle_ps更好\等于\更差?

Ice Lake有2个/时钟vshufps与1个/时钟vunpcklpd,根据 uops.info 在实际硬件上的测试,在端口1或端口5上运行。一定要用_mm256_shuffle_ps. 微不足道的额外代码大小成本在早期的CPU上可能根本不会受到伤害,并且对于ICL的未来利益来说可能是值得的,除非您确定端口5不会成为瓶颈。

Ice Lake在端口1上有一个第二个随机单元,可以处理一些常见的XMM和通道内YMM随机播放,包括vpshufb和显然一些2输入随机播放,如vshufps。 我不知道为什么它不只是vunpcklpd解码为具有该控制向量的vshufps,或者设法在端口 1 上运行该随机播放。 我们知道随机播放硬件本身可以进行随机播放,所以我想这只是控制硬件设置隐式随机播放的问题,以某种方式将操作码映射到随机播放控件。

除此之外,它在较旧的AVX CPU上相同或更好;没有CPU会在其他PS指令之间使用PD洗牌而受到惩罚。 任何现有 CPU 上的唯一区别是代码大小。 像K8和Core 2这样的旧CPU的pd洗牌速度比ps快,但是没有AVX的CPU有这个弱点的洗牌单元。 此外,AVX 非破坏性指令在哪个操作数必须作为目标之间存在电平差异。


正如你从Godbolt链接中看到的,在洗牌之前/之后没有额外的指令。 "cast"内部函数不是在进行转换,只是重新解释以保持C++类型系统满意,因为英特尔决定为__m256__m256d(与__m256i),而不是具有一个通用的 YMM 类型。 他们选择不单独uint8x16与 不过,uint32x4ARM 的方式向量;对于整数 SIMD 只需__m256i.

因此,编译器没有必要为强制转换发出额外的指令,在实践中确实如此;他们不会引入额外的vmovaps/apd寄存器副本或类似的东西。

如果你正在使用clang,

你可以方便地编写它,让clang的shuffle优化器为你发出vunpcklpd。 或者在其他情况下,无论如何都要做任何它要做的事情;有时它会做出比来源更糟糕的选择,但通常它做得很好。

Clang在-march=icelake-client上犯了这个错误,即使你写_mm256_shuffle_ps,仍然使用vunpcklpd。 (或者根据周围的代码,可能会将该随机播放优化为其他内容的一部分。

相关错误报告。