【问题标题】:How to store lower or higher values from AVX/AVX2(YMM) register to memory like the SSE movlps/movhps does?如何像 SSE movlps/movhps 一样将 AVX/AVX2(YMM) 寄存器中的较低或较高值存储到内存中?
【发布时间】:2013-01-14 00:03:52
【问题描述】:

是否有任何现有指令可以将 256 位 AVX/AVX2(YMM) 寄存器中的较低或较高值存储到内存地址,就像 SSE 指令 movlps/movhps 一样?

或者还有其他方法可以实现吗?

任何帮助将不胜感激,谢谢!

【问题讨论】:

  • 您可以使用insert/extract instructions。那些会将它们拉到另一个寄存器中。所以你仍然需要一个单独的加载/存储指令。但话虽如此,这与仅使用 128 位置换来交换两半没有任何不同。
  • 感谢@Mysticial!我发现 AVX2 vextractf128 可能适用于此。

标签: x86 sse simd avx avx2


【解决方案1】:

vmovdqu [rdi], xmm0 存储low128。

VEXTRACTI128 xmm1/m128, ymm2, 1 存储high128。可能您可以通过将提取的结果分配给内存引用来让编译器生成对内存的存储。

vextracti128 / f128 需要 2 微秒,即使在融合域 (Haswell) 中也是如此,所以 IDK 使用立即操作数 0 对其进行编码的意义是什么。 (直到 AVX512,当立即索引而不是 movh 变得相关时,因为他们不知道他们将用 EVEX 替换 VEX 用于 AVX512)。将 AVX2 与 xmm regs 和 AVX2 与 ymm regs 混合没有任何惩罚,因此您只需使用 xmm 版本的 128b 存储即可获得低 128,就像您可以通过引用 eax 获得 64b GP ​​reg 的低 32而不是rax

在使用内在函数时,转换东西可能很烦人,所以幸运的是,编译器会将_mm256_extracti128_si256 (vec, 0) 编译为相应xmm reg 的vmovdqu。但是如果你的编译器没有,如果你让它生成vmovdqu,你的代码会更快。 (如果地址对齐,movdquvmovdqa 一样快,就像非 mov AVX 内存访问一样。)

【讨论】:

  • 另一种解决方案是vmovaps XMMWORD PTR [rdi], xmm0 用于较低的 128 部分。 GCC/clang 将 _mm_store_ps(ptr, _mm256_castps256_ps128(v)) 编译为 Haswell 及以上版本。
  • @plasmacel:没有 CPU 对存储有旁路延迟惩罚,因此 movups / movaps 在旧版 SSE(非 VEX)编码中保存一个字节的机器代码。不过,vmovaps 优于 vmovdqa 没有任何意义,但也没有缺点,所以我想它使 gcc 的代码更容易始终使用 ...ps 商店。
猜你喜欢
  • 2015-10-25
  • 2011-11-04
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
  • 1970-01-01
  • 2011-08-23
  • 2017-06-08
  • 2020-02-25
相关资源
最近更新 更多