我错过了AVX512的固有_mm512_round_ps
(它仅适用于KNC)。知道为什么没有这个吗?
什么是好的解决方法?
将_mm256_round_ps
应用于上半部分和下半部分并融合结果?
使用_mm512_add_round_ps
,其中一个参数为零?
谢谢!
答案 0 :(得分:4)
__m512 nearest_integer = _mm512_roundscale_ps(input_vec, _MM_FROUND_TO_NEAREST_INT|_MM_FROUND_NO_EXC);
相关:AVX512DQ _mm512_reduce_pd
或_ps
将减去整数部分(以及指定数量的前导分数位),将输入范围减小到仅小数部分。 asm docs for vreducepd
最详细。
对于FP指令,EVEX前缀允许覆盖默认的舍入方向{er}
and setting suppress-all-exceptions {sae}
。 (这是内在函数的..._round_ps()
版本的用途。)但它没有“round to integer”选项;你还需要一个单独的asm指令。
vroundps xy, xy/mem, imm8
未升级到AVX512。实际上它确实:相同的操作码有一个新的EVEX版本的助记符,使用SSE和VEX编码中保留的立即高4位。
vrndscaleps xyz, xyz/mem/m32broadcast, imm8
在ss / sd / ps / pd flavor中可用。 imm8的高4位指定要舍入到的小数位数。在这些术语中,舍入到最接近的整数是舍入到0分数位。舍入到最接近的0.5
将舍入到1分数位。它与缩放2 ^ M,舍入到最接近的整数,然后缩小(完成没有溢出)相同。
我认为该字段是无符号的,因此您不能使用M = -1来舍入到偶数。 ISA参考手册没有提到签名,所以我倾向于无条件最有可能。
字段的低4位指定与roundps
类似的舍入模式。像往常一样,PD
指令的roundps
版本(因为它按字母顺序排在第一位)。
高4位= 0时,它的行为与roundpd
相同:它们对低4位使用相同的编码。指令具有相同的巧合并非巧合操作码,只是不同的前缀。
(我很好奇,如果AVX512 CPU上的SSE或VEX __m512 _mm512_roundscale_ps( __m512 a, int imm);
实际上会根据高4位进行扩展;它表示它们是“保留”而不是“忽略”。但可能不是。)< / p>
__m512 _mm512_mask_roundscale_round_ps(__m512 s, __mmask16 k, __m512 a, int imm, int sae);
是简单的内在。请参阅has the diagram
merge-masking + SAE-override版本为sae
。 roundscale
imm8
无法对其_MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC
进行操作,因此无法对_MM_FROUND_CUR_DIRECTION
进行操作,因此它有点无意义。
您可以使用_MM_FROUND_NO_EXC
等常量Intel's intrinsic finder 来向上舍入,向下舍入或截断为零,或者通常最接近偶数为tiebreak这是IEEE默认的舍入模式。或vrndscaleps
使用当前模式。 vrndscaleps zmm0 {k1}, zmm1, {rz-sae}
禁止在MXCSR中设置不精确的异常位。
您可能想知道为什么vrndscaleps zmm0{k1}, [rdi]{m32bcst}, imm8
需要任何立即位来指定舍入方向,只需使用EVEX前缀来覆盖k1
的舍入方向(或者等等)正确的语法是; NASM似乎不接受我找到的任何例子。)
答案是显式舍入仅适用于512位向量或标量,并且仅适用于寄存器操作数。 (它重新利用3个用于设置向量长度的EVEX位(如果支持AVX512VL),并区分广播存储器操作数和向量.EVEX位根据上下文重载,以将更多功能打包到有限的空间中。)
因此,在imm8中进行舍入控制可以使vroundps
从内存中广播浮点数,将其舍入,并根据掩码寄存器 a b c country
0 5 7 11 Morocco
1 5 9 9 Nigeria
2 6 2 13 Spain
将其合并到现有寄存器中。全部在单个指令中,在SKX上解码为大约3个uop,假设它与e
相同。 (documented for _mm_round_pd
/ _mm256_round_pd
)。