c++ - _mm256_extractf32x4_ps 和 _mm256_extractf128_ps 之间的区别

标签 c++ c intrinsics avx avx512

_mm256_extractf32x4_ps 的英特尔文档和 _mm256_extractf128_ps读起来很像。我只能发现两个不同之处:

  1. _mm256_extractf128_ps 接受一个const int 作为参数,_mm256_extractf32x4_ps 接受一个int。这应该没有任何区别。
  2. _mm256_extractf128_ps 需要 AVX 标志,而 _mm256_extractf32x4_ps 需要 AVX512F + AVX512VL,这使得前者看起来更适合跨 CPU。

_mm256_extractf32x4_ps 存在的理由是什么?

最佳答案

是的,int arg 在这两种情况下都必须成为立即数,因此在不断传播之后它需要成为编译时常量。

是的,没有理由为 C 中的 AVX-512VL 版本使用 C 内在的无掩码版本;只有 _mm256_mask_extractf32x4_ps_mm256_maskz_extractf32x4_ps 才真正有意义。

在 asm 中,您可能需要 AVX-512 版本,因为访问 ymm16..31 需要 EVEX 编码,并且只有 VEXTRACTF32X4 具有 EVEX 编码。但这是 IMO,您的 C 编译器应该能够为您处理,无论您编写哪个内在函数。

如果您的编译器完全优化了内在函数,它就会知道您正在编译时启用了 AVX-512,并且会使用允许它与在寄存器分配期间选择的寄存器一起使用的任何混洗。 (例如,clang 有一个非常积极的洗牌优化器,经常使用不同的指令或尽可能将洗牌变成更便宜的混合。或者有时会挫败编写比洗牌优化器提出的更智能代码的努力)。

但一些编译器(尤其是 MSVC)优化内在函数,甚至不通过它们进行常量传播。我想Intel ICC也是这样的。 (我没有看过 ICX,他们更新的基于 clang/LLVM 的编译器。)这个模型使得使用 AVX-512 内在函数成为可能,而无需告诉编译器可以使用 AVX-512 指令它自己的。在这种情况下,将 _mm256_extractf128_ps 编译为 VEXTRACTF32X4 以允许使用 YMM16..31 可能会出现问题(特别是如果同一 block 中没有其他 AVX-512VL 指令,或者如果这个确实执行的话肯定会执行)。

关于c++ - _mm256_extractf32x4_ps 和 _mm256_extractf128_ps 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70887045/

相关文章:

c++ - 在 Windows 7 上构建 64 位 Qt? (Qt 5.0.2, MS Visual Studio 2012)

c++ - 从 C++ 代码将多行 bash 脚本作为字符串运行

c - 使用 C 分割 wav 文件

c - 将 __m256 拆分为两个 __m128 寄存器

c++ - boost::variant 对象的 getter

c++ - 如何将 int unique_ptr 转换为 void unique_ptr?

c++ - sscanf 从八进制转换 : How does it know?

c - undefined reference

assembly - 访问封装在 128 位寄存器中的任意 16 位元素

gcc - 英特尔编译器/LLVM 上的并行位存储/并行位提取?