我缺少_mm512_round_ps
AVX512 的内在特性(它仅适用于 KNC)。知道为什么这不可用吗?
什么是一个好的解决方法?
适用
_mm256_round_ps
于上半部和下半部并融合结果?使用
_mm512_add_round_ps
一个参数为零?
谢谢!
我缺少_mm512_round_ps
AVX512 的内在特性(它仅适用于 KNC)。知道为什么这不可用吗?
什么是一个好的解决方法?
适用_mm256_round_ps
于上半部和下半部并融合结果?
使用_mm512_add_round_ps
一个参数为零?
谢谢!
__m512 nearest_integer = _mm512_roundscale_ps(input_vec, _MM_FROUND_TO_NEAREST_INT|_MM_FROUND_NO_EXC);
相关:AVX512DQ_mm512_reduce_pd
或_ps
将减去整数部分(和指定数量的前导小数位),将您的输入范围缩小到仅小数部分。 asm 文档vreducepd
有最详细的信息。
EVEX 前缀允许覆盖默认舍入方向{er}
和设置 suppress-all-exceptions{sae}
,用于 FP 指令。(这就是..._round_ps()
内在函数版本的用途。)但它没有“四舍五入”选项。你仍然需要一个单独的 asm 指令。
vroundps xy, xy/mem, imm8
没有升级到 AVX512。实际上确实如此:对于 EVEX 版本,相同的操作码有一个新的助记符,使用在 SSE 和 VEX 编码中保留的立即数的高 4 位。
vrndscaleps xyz, xyz/mem/m32broadcast, imm8
有 ss/sd/ps/pd 口味。 imm8 的高 4 位指定要舍入到的小数位数。在这些术语中,四舍五入到最接近的整数就是四舍五入到 0 小数位。舍入到最接近的0.5
值将舍入到 1 个小数位。它与按 2^M 缩放相同,四舍五入到最接近的整数,然后按比例缩小(在没有溢出的情况下完成)。
我认为该字段是无符号的,因此您不能使用 M=-1 舍入为偶数。ISA ref 手册没有提到签名,所以我倾向于 unsigned 是最有可能的。
该字段的低 4 位指定舍入模式,如roundps
。像往常一样,PD
指令的版本有图表(因为它是按字母顺序排列的)。
高 4 位 = 0 时,它的行为与 相同roundps
:它们对低 4 位使用相同的编码。 指令具有相同的操作码并非巧合,只是前缀不同。
(我很好奇roundpd
AVX512 CPU 上的 SSE 或 VEX 是否真的会根据高 4 位进行扩展;它说它们是“保留”而不是“忽略”。但可能不是。)
__m512 _mm512_roundscale_ps( __m512 a, int imm);
是简洁的内在。查看英特尔的内在查找器
合并屏蔽 + SAE 覆盖版本是__m512 _mm512_mask_roundscale_round_ps(__m512 s, __mmask16 k, __m512 a, int imm, int sae);
. 但是,对于已经无法使用它的sae
操作数,您无能为力,所以它有点毫无意义。roundscale
imm8
您可以使用为/_MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC
记录的等常量_mm_round_pd
_mm256_round_pd
来向上、向下舍入或截断为零,或者通常最接近 IEEE 默认舍入模式的 even-as-tiebreak。或者_MM_FROUND_CUR_DIRECTION
使用任何当前模式。 _MM_FROUND_NO_EXC
禁止在 MXCSR 中设置不精确异常位。
您可能想知道为什么vrndscaleps
需要任何直接位来指定舍入方向,而您可以使用 EVEX 前缀来覆盖舍入方向vrndscaleps zmm0 {k1}, zmm1, {rz-sae}
(或任何正确的语法;NASM 似乎不接受我找到的任何示例。 )
答案是显式舍入仅适用于 512 位向量或标量,并且仅适用于寄存器操作数。(它重新使用了 3 个 EVEX 位来设置向量长度(如果支持 AVX512VL),并区分广播内存操作数与向量。EVEX 位根据上下文重载,以将更多功能打包到有限的空间中。)
因此,在 imm8 中进行舍入控制可以vrndscaleps zmm0{k1}, [rdi]{m32bcst}, imm8
从内存中广播浮点数,对其进行舍入,然后根据掩码寄存器将其合并到现有寄存器中k1
。假设它与vroundps
. (http://agner.org/optimize/)。