使用 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 double
和 float
。
如果您的除数向量是编译时常量(或重复用于多个除数),请参阅 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 位整数与掩码相除的主要内容,如果未能解决你的问题,请参考以下文章
给定一个 int 偏移向量,如何使用 AVX512 内在函数收集单个字节?