使用 AVX512 或 SVML 内在函数将压缩的 16 位整数与掩码相除

Posted

技术标签:

【中文标题】使用 AVX512 或 SVML 内在函数将压缩的 16 位整数与掩码相除【英文标题】:Dividing packed 16-bit integer with mask using AVX512 or SVML intrinsics 【发布时间】:2020-02-04 04:49:53 【问题描述】:

我正在寻找一种用掩码(例如__mmask16)划分压缩 16 位整数的解决方案。 _mm512_mask_div_epi32 内在函数似乎不错;但是它们只支持压缩的 32 位整数,这不必要地迫使我在使用前将压缩的 16 位扩展为压缩的 32 位。

【问题讨论】:

【参考方案1】:

_mm512_mask_div_epi32 不是真正的内在函数;这是一个英特尔 SVML 功能。 x86 没有 SIMD 整数除法,只有 SIMD FP doublefloat

如果您的除数向量是编译时常量(或重复用于多个除数),请参阅 https://libdivide.com/ 了解使用乘法逆的精确除法。

否则,最好的办法是转换为可以精确表示每个 16 位整数的单精度 FP。如果_mm512_mask_div_epi32 做了任何额外的工作来处理 FP32 不能 完全代表所有可能的int32_t 的事实,那么这对您的用例来说是浪费的。

(一些未来的 CPU 可能在 IA 内核中支持某种 16 位 FP,而不仅仅是 GPU,但目前利用高吞吐量硬件 div/sqrt SIMD 执行单元的最佳方式是通过转换为float。例如,对于带有单个微指令的 Skylake vdivps ymm,每 5 个时钟周期一个 __m256,或者对于带有 3 个微指令的 __m512,每 10 个时钟周期一个 vdivps zmm)

【讨论】:

我刚刚意识到_mm512_mask_div_epi32 没有任何对应的asm,或者不是你所说的真正的内在。我猜它会被编译成普通的整数除法 asm,因此不能减少运行时间。我将尝试转换为一些vdivps 函数,然后转换回epi32 @thnghh:我假设 _mm512_mask_div_epi32 的内部实现使用 SIMD float 甚至 double 来避免 32 位整数的舍入错误,如果它被记录为始终准确的话.不解包为整数除法的标量!它还可以将舍入模式设置为截断,以确保在进行截断转换回整数之前,结果不会在幅度上四舍五入。 (AVX512 可以通过舍入模式覆盖有效地做到这一点。)

以上是关于使用 AVX512 或 SVML 内在函数将压缩的 16 位整数与掩码相除的主要内容,如果未能解决你的问题,请参考以下文章

缺少掩码的 AVX-512 内在函数?

给定一个 int 偏移向量,如何使用 AVX512 内在函数收集单个字节?

使用 intel 内在函数将压缩的 8 位整数乘以浮点向量

avx512中比较内在指令的不同语义?

使用 AVX512 或 AVX2 计算所有压缩 32 位整数之和的最快方法

发行版将 GCC 升级到 5.5.0 后,AVX512 内在函数头会产生许多错误