_mm512_load_epi32 和 _mm512_load_si512 有什么区别?

What is the difference between _mm512_load_epi32 and _mm512_load_si512?

英特尔内在函数指南简单地指出 _mm512_load_epi32:

Load[s] 512-bits (composed of 16 packed 32-bit integers) from memory into dst

_mm512_load_si512:

Load[s] 512-bits of integer data from memory into dst

这两者有什么区别?文档不清楚。

没有区别,只是愚蠢的多余命名。为清楚起见,请使用 _mm512_load_si512 谢谢,英特尔。像往常一样,更容易理解 AVX512 的底层 asm,然后你就可以看到笨拙的内在命名试图表达的意思。或者至少您可以理解我们是如何以建议 _mm512_load_epi32_mm512_load_si512.

的不同文档结束的

几乎所有 AVX512 指令都支持合并屏蔽和零屏蔽。 (例如,vmovdqa32 可以像 vmovdqa32 zmm0{k1}{z}, [rdi] 那样对矢量元素进行零位加载,其中 k1 有一个零位),这就是为什么矢量加载和按位运算等不同元素大小版本的原因存在。 (例如 vpxord vs. vpxorq)。

但这些内在函数适用于无屏蔽版本。元素大小完全无关紧要。 我猜 _mm512_load_epi32 的存在是为了与 _mm512_mask_load_epi32(合并掩码)和 _mm512_maskz_load_epi32(零掩码)保持一致。请参阅 vmovdqa32 asm 指令的文档。

例如_mm512_maskz_loadu_epi64(0x55, x) 加载时免费将奇数元素归零。 (至少它是免费的,如果将 0x55 放入 k 寄存器的成本可以提升到循环之外。如果我们没有击败编译器将负载折叠到内存中的机会ALU 指令的操作数。)

当元素全部原样加载到目的地时,元素边界是没有意义的。这就是为什么 AVX2 和更早版本没有不同元素大小版本的按位布尔值,例如 _mm_xor_si128 和 loads/stores,例如 _mm_load_si128.


一些编译器不支持 未对齐 未屏蔽加载 的元素宽度名称。例如当前的 gcc 不支持 _mm512_loadu_epi64,即使它支持 _mm512_load_epi64,因为第一个 gcc 版本完全支持 AVX512 内在函数。 (参见

没有 CPU 的选择 vmovdqa64vmovdqa32 对效率有任何影响,因此试图暗示无论数据的自然元素宽度如何,编译器都会使用其中一种。

只有 FP 与整数可能对负载很重要,而英特尔的内在函数已经为此使用了不同的类型(__m512__m512i)。