如何用 gcc 或 clang 模仿_mm256_loadu_epi32?

How to emulate _mm256_loadu_epi32 with gcc or clang?

本文关键字:mm256 loadu epi32 模仿 何用 gcc clang      更新时间:2023-10-16

英特尔的内在指南列出了内在_mm256_loadu_epi32

_m256i _mm256_loadu_epi32 (void const* mem_addr);
/*
Instruction: vmovdqu32 ymm, m256
CPUID Flags: AVX512VL + AVX512F
Description
Load 256-bits (composed of 8 packed 32-bit integers) from memory into dst.
mem_addr does not need to be aligned on any particular boundary.
Operation
a[255:0] := MEM[mem_addr+255:mem_addr]
dst[MAX:256] := 0
*/

但是 clang 和 gcc 并没有提供这种内在的东西。相反,它们(在文件avx512vlintrin.h中(仅提供屏蔽版本

_mm256_mask_loadu_epi32 (__m256i, __mmask8, void const *);
_mm256_maskz_loadu_epi32 (__mmask8, void const *);

归结为相同的指令vmovdqu32.我的问题:我如何模仿_mm256_loadu_epi32

inline _m256i _mm256_loadu_epi32(void const* mem_addr)
{
/* code using vmovdqu32 and compiles with gcc */
}

不写汇编,即只使用可用的内联函数?

就像正常人一样使用_mm256_loadu_si256。 AVX512内在唯一给你的就是一个更好的原型(const void*而不是const __m256i*(,所以你不必写丑陋的演员表。

@chtz建议您可能仍然希望自己编写包装器函数以获取void*原型。 但不要称它为_mm256_loadu_epi32;一些未来的GCC版本可能会添加它以与英特尔的文档兼容并破坏您的代码。

从另一个角度来看,不幸的是,编译器不会将其视为 AVX1 内部函数,但我想不优化内部函数的编译器,并且允许您使用尚未启用的 ISA 扩展的内部函数,需要这种线索来知道他们何时可以使用 ymm16-31。


你甚至不希望编译器在你不屏蔽时发出vmovdqu32 ymm;vmovdqu ymm更短,做完全相同的事情,与EVEX编码指令混合不会受到任何惩罚。 编译器如果想要加载到 ymm16 中,则始终可以使用vmovdqu3264。31,否则您希望它使用较短的 VEX 编码 AVX1vmovdqu

我很确定 GCC 对待_mm256_maskz_epi32(0xffu,ptr)_mm256_loadu_si256((const __m256i*)ptr)完全相同,无论您使用哪一个,都会制作相同的 asm。 它可以优化0xffu掩码,只需使用未屏蔽的负载,但您的源中不需要额外的复杂性。

但不幸的是,当启用 GCC9 和更早版本时,AVX512VL会悲观地vmovdqu32 ymm0, [mem](例如-march=skylake-avx512( 即使您写_mm256_loadu_si256. 这是一个错过的优化,GCC 错误 89346

只要没有掩码,您使用哪个 256 位负载内部函数(对齐与未对齐除外(并不重要。

相关:

  • 错误:"_mm512_loadu_epi64"未在此范围内声明
  • _mm512_load_epi32和_mm512_load_si512有什么区别?
相关文章:
  • 没有找到相关文章