_mm_movelh_ps 的 AVX 等价物

AVX equivalent for _mm_movelh_ps

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

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

由于强制转换应该是无操作的,这 better\equal\worse 比使用 _mm256_shuffle_ps 性能更好吗?

此外,如果确实如此,如果有人能用简单的语言解释(我对汇编和微体系结构的理解非常有限)为什么人们应该更喜欢没有控制整数的指令,那就太好了。

提前致谢

补充说明: Clang 实际上将 shuffle 优化为 vunpcklpd: https://godbolt.org/z/9XFP8D 所以看来我的想法还不错。但是,GCC 和 ICC 创建了随机播放指令。

避免立即数节省 1 个字节的机器代码大小;就这样。出于性能方面的考虑,它位于列表的底部,但由于这个原因,所有其他类似 _mm256_unpacklo_pd 和隐式 "control" 的随机播放都比直接控制字节好一点。

(但是将控制操作数放在另一个向量中,如 vpermilps can 或 vpermd requires 通常更糟,除非你在 long-运行 中有一些奇怪的前端瓶颈ning 循环,并可以在循环外加载 shuffle 控件。不太合理,此时你必须在 asm 中手工编写才能关心代码 size/alignment;在 C++ 中,这仍然不是什么真的可以直接控制。)

Since the casts are supposed to be no-ops, is this better\equal\worse than using _mm256_shuffle_ps regarding performance?

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

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

除此之外,它在较旧的 AVX CPU 上相同或更好;没有 CPU 会因在其他 PS 指令之间使用 PD 随机播放而受到惩罚。任何现有 CPU 的唯一不同是代码大小。 K8 和 Core 2 等旧 CPU 的 pd 洗牌速度比 ps 快,但没有带有 AVX 的 CPU 具有具有该弱点的洗牌单元。此外,AVX 非破坏性指令级别差异,其中操作数必须是目标。


正如您从 Godbolt link 中看到的那样,随机播放的额外指令为零 before/after。 "cast" 内在函数不进行转换,只是重新解释以使 C++ 类型系统满意,因为英特尔决定为 __m256__m256d(与 __m256i 提供单独的类型),而不是拥有一种通用的 YMM 类型。不过,他们选择不像 ARM 那样使用单独的 uint8x16uint32x4 向量;对于整数 SIMD 只是 __m256i.

所以编译器不需要为强制转换发出额外的指令,在实践中确实如此;他们不会引入额外的 vmovaps/apd 注册副本或类似的东西。


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

Clang 用 -march=icelake-client 搞错了,即使你写 _mm256_shuffle_ps 仍然使用 vunpcklpd。 (或者根据周围的代码,可能会将洗牌优化为其他内容的一部分。)

Related bug report.