Wal*_*ter 5 c c++ intrinsics avx512
英特尔的内在指南列出了内在的_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
*/
Run Code Online (Sandbox Code Playgroud)
但是 clang 和 gcc 不提供这种内在的。相反,他们avx512vlintrin.h仅提供(在文件中)屏蔽版本
_mm256_mask_loadu_epi32 (__m256i, __mmask8, void const *);
_mm256_maskz_loadu_epi32 (__mmask8, void const *);
Run Code Online (Sandbox Code Playgroud)
归结为相同的指令vmovdqu32。我的问题:我怎样才能模仿_mm256_loadu_epi32:
inline _m256i _mm256_loadu_epi32(void const* mem_addr)
{
/* code using vmovdqu32 and compiles with gcc */
}
Run Code Online (Sandbox Code Playgroud)
无需编写程序集,即仅使用可用的内在函数?
_mm256_loadu_si256像正常人一样使用。AVX512 内在给你的唯一东西是一个更好的原型(const void*而不是const __m256i*)。
@chtz 建议您可能仍然想自己编写一个包装函数来获取void*原型。但不要叫它_mm256_loadu_epi32; 某些未来的 GCC 版本可能会添加它以与英特尔的文档兼容并破坏您的代码。
vmovdqu32 ymm当您不屏蔽时,您甚至不希望编译器发出;vmovdqu ymm更短,做完全相同的事情,与 EVEX 编码的指令混合没有损失。编译器总是可以使用vmovdqu32or64如果它想加载到 ymm16..31 中,否则您希望它使用较短的 VEX 编码 AVX1 vmovdqu。
我很确定 GCC 的处理方式与 asm_mm256_maskz_epi32(0xffu,ptr)完全相同,_mm256_loadu_si256((const __m256i*)ptr)并且无论您使用哪个 asm。它可以优化0xffu掩码并简单地使用未掩码的负载,但您的源不需要额外的复杂性。
但不幸的vmovdqu32 ymm0, [mem]是,-march=skylake-avx512即使在您编写_mm256_loadu_si256. 这是一个遗漏的优化,GCC Bug 89346。
只要没有屏蔽,您使用哪个 256 位加载内在函数(对齐与未对齐除外)都没有关系。
有关的:
| 归档时间: |
|
| 查看次数: |
517 次 |
| 最近记录: |