如何用 gcc 或 clang 模仿_mm256_loadu_epi32?
How to emulate _mm256_loadu_epi32 with gcc or clang?
英特尔的内在指南列出了内在_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 中,则始终可以使用vmovdqu32
或64
。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有什么区别?
- 没有找到相关文章