_mm256_extractf32x4_ps 和 _mm256_extractf128_ps 之间的区别

Difference between _mm256_extractf32x4_ps and _mm256_extractf128_ps

_mm256_extractf32x4_ps and _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 在这两种情况下都必须成为立即数,因此在不断传播后它需要成为一个 compile-time 常数。

是的,没有理由为 C 中的 AVX-512VL 版本使用 no-masking 版本的 C 内在函数;只有 _mm256_mask_extractf32x4_ps_mm256_maskz_extractf32x4_ps.

才有意义

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

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

但是一些编译器(尤其是 MSVC)优化内在函数,甚至不通过它们constant-propagation。我想Intel ICC也是这样的。 (我没有看过 ICX,他们更新的 clang/LLVM-based 编译器。)这个模型可以在不告诉编译器 可以使用 AVX- 的情况下使用 AVX-512 内在函数。 512 指令本身。在这种情况下,将 _mm256_extractf128_ps 编译为 VEXTRACTF32X4 以允许使用 YMM16..31 可能是一个问题(特别是如果同一块中没有其他 AVX-512VL 指令,或者肯定会执行如果这个有的话)。