我来到了这两个函数:
_mm512_setzero_epi32()
_mm512_setzero_si512()
从逻辑上讲,他们是做同样的事情。然后我检查了the generated Assembly并且在不同的优化级别下也发现了相同的情况。
这是一个简单的问题:为什么 AVX512 有如此重复的设计来将 int 设置为 0?
最佳答案
_mm512_setzero_epi32()
100% 冗余,没有理由使用
出于编码风格的原因,我建议不要这样做。它不遵循 _mm_setzero_si128()
相同的模式/_mm256_setzero_si256()
用于返回全零的 SIMD 整数向量,其中 _mm512_setzero_si512()
如下。
情况与useless and redundant非常相似_mm512_loadu_epi32
(这会令人困惑地加载整个 64 字节向量,而不是 4 字节标量)。 并非所有编译器都支持 _mm512_loadu_epi32
或_mm512_loadu_epi64
, _mm512_setzero_epi32
也可能属于这种情况;避免它而支持更标准和明显的另一个原因。
对于像_mm512_loadu_epi32
这样的冗余内在函数和_mm512_and_epi32
,它们是像 _mm512_maskz_loadu_epi32
这样的模式的一部分和_mm512_mask_loadu_epi32
;屏蔽需要元素大小,并且具有未屏蔽的内在函数至少形成类似 _mm512_add_epi32
的模式。其中同一操作的不同元素大小版本必须存在,并且不存在 _si512
版本。
但是没有合并掩码或零掩码setzero
当前版本的内在函数指南中包含内在函数。 因此,setzero_epi32
没有模式。成为其中的一部分。
在asm中,没有vpxor zmm
,仅 vpxord
and vpxorq
,因为基本上所有 AVX-512 指令都支持掩码,这意味着必须有一个元素大小。 (对于像 vmovdqa64
/32
这样的 Action 也是如此。)
_mm512_setzero_epi32()
也是如此暗示使用vpxord
?不,英特尔的内在函数指南实际上将其记录为使用 vpxorq
,像所有其他 512 位归零内在函数一样(包括 _mm512_setzero_ps()
- 有趣的事实;EVEX vxorps
需要 AVX512DQ 扩展,KNL Xeon Phi 不支持,仅在主流(Skylake-avx512 及更高版本)CPU 中支持)。
至于编译器实际选择使用什么归零指令,可以是其中之一,而且没有区别。
关于simd - 为什么AVX512中有重复的置零功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74775831/