AVX 512 缺少内在 _mm512_round_ps
instrinsic _mm512_round_ps is missing for AVX512
我缺少 AVX512 的固有 _mm512_round_ps
(它仅适用于 KNC)。知道为什么这不可用吗?
什么是好的解决方法?
将_mm256_round_ps
应用于上半部分和下半部分并融合结果?
使用 _mm512_add_round_ps
且一个参数为零?
谢谢!
TL:DR: AVX512F
__m512 nearest_integer = _mm512_roundscale_ps(input_vec, _MM_FROUND_TO_NEAREST_INT|_MM_FROUND_NO_EXC);
相关:AVX512DQ_mm512_reduce_pd
or _ps
will subtract the integer part (and a specified number of leading fraction bits), range-reducing your input to only the fractional part. asm docs for vreducepd
最详细
EVEX 前缀允许覆盖默认舍入方向 ,用于 FP 指令。 (这就是内在函数的 ..._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 种口味。 imm8 的高 4 位指定要四舍五入的小数位数。在这些术语中,舍入到最接近的整数就是舍入到 0 个小数位。舍入到最接近的 0.5
将舍入到 1 个小数位。这与按 2^M 缩放,四舍五入到最接近的整数,然后缩小(在没有溢出的情况下完成)相同。
我认为这个字段是无符号的,所以你不能使用 M=-1 来四舍五入到偶数。 ISA 参考手册没有提到签名,所以我倾向于无符号是最有可能的。
该字段的低 4 位指定与 roundps
类似的舍入模式。和往常一样,指令 has the diagram 的 PD
版本(因为它按字母顺序排在第一位)。
高 4 位 = 0,它的行为与 roundps
相同:它们对低 4 位使用相同的编码。 这不是巧合这些指令具有相同的操作码,只是前缀不同。
(我很好奇 AVX512 CPU 上的 SSE 或 VEX roundpd
是否会根据高 4 位进行缩放;它说它们是 "reserved" 而不是 "ignored"。但可能不是。)
__m512 _mm512_roundscale_ps( __m512 a, int imm);
是简洁的内在。参见 Intel's intrinsic finder
合并屏蔽 + 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
等常数 documented for _mm_round_pd
/ _mm256_round_pd
,向上、向下或截断为零,或通常最接近的even-as-tiebreak 这是 IEEE 默认的舍入模式。或者 _MM_FROUND_CUR_DIRECTION
使用当前模式。 _MM_FROUND_NO_EXC
禁止在 MXCSR 中设置不准确的异常位。
您可能想知道为什么 vrndscaleps
需要任何立即位来指定舍入方向,而您可以只使用 EVEX 前缀来覆盖 vrndscaleps zmm0 {k1}, zmm1, {rz-sae}
[=90 的舍入方向=](或任何正确的语法;NASM 似乎不接受我找到的任何示例。)
答案是显式舍入仅适用于 512 位向量或标量,并且仅适用于寄存器操作数。 (它将 3 个 EVEX 位重新用于设置向量长度(如果支持 AVX512VL),并区分广播内存操作数与向量。EVEX 位根据上下文重载以将更多功能打包到有限的 space 中。)
因此在 imm8 中拥有舍入控制使得vrndscaleps zmm0{k1}, [rdi]{m32bcst}, imm8
可以从内存广播一个浮点数,舍入它,并根据掩码寄存器将其合并到现有寄存器中k1
.所有这些都在一条指令中,假设它与 vroundps
相同,在 SKX 上解码为大约 3 微指令。 (http://agner.org/optimize/).
我缺少 AVX512 的固有 _mm512_round_ps
(它仅适用于 KNC)。知道为什么这不可用吗?
什么是好的解决方法?
将
_mm256_round_ps
应用于上半部分和下半部分并融合结果?使用
_mm512_add_round_ps
且一个参数为零?
谢谢!
TL:DR: AVX512F
__m512 nearest_integer = _mm512_roundscale_ps(input_vec, _MM_FROUND_TO_NEAREST_INT|_MM_FROUND_NO_EXC);
相关:AVX512DQ_mm512_reduce_pd
or _ps
will subtract the integer part (and a specified number of leading fraction bits), range-reducing your input to only the fractional part. asm docs for vreducepd
最详细
EVEX 前缀允许覆盖默认舍入方向 ..._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 种口味。 imm8 的高 4 位指定要四舍五入的小数位数。在这些术语中,舍入到最接近的整数就是舍入到 0 个小数位。舍入到最接近的 0.5
将舍入到 1 个小数位。这与按 2^M 缩放,四舍五入到最接近的整数,然后缩小(在没有溢出的情况下完成)相同。
我认为这个字段是无符号的,所以你不能使用 M=-1 来四舍五入到偶数。 ISA 参考手册没有提到签名,所以我倾向于无符号是最有可能的。
该字段的低 4 位指定与 roundps
类似的舍入模式。和往常一样,指令 has the diagram 的 PD
版本(因为它按字母顺序排在第一位)。
高 4 位 = 0,它的行为与 roundps
相同:它们对低 4 位使用相同的编码。 这不是巧合这些指令具有相同的操作码,只是前缀不同。
(我很好奇 AVX512 CPU 上的 SSE 或 VEX roundpd
是否会根据高 4 位进行缩放;它说它们是 "reserved" 而不是 "ignored"。但可能不是。)
__m512 _mm512_roundscale_ps( __m512 a, int imm);
是简洁的内在。参见 Intel's intrinsic finder
合并屏蔽 + 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
等常数 documented for _mm_round_pd
/ _mm256_round_pd
,向上、向下或截断为零,或通常最接近的even-as-tiebreak 这是 IEEE 默认的舍入模式。或者 _MM_FROUND_CUR_DIRECTION
使用当前模式。 _MM_FROUND_NO_EXC
禁止在 MXCSR 中设置不准确的异常位。
您可能想知道为什么 vrndscaleps
需要任何立即位来指定舍入方向,而您可以只使用 EVEX 前缀来覆盖 vrndscaleps zmm0 {k1}, zmm1, {rz-sae}
[=90 的舍入方向=](或任何正确的语法;NASM 似乎不接受我找到的任何示例。)
答案是显式舍入仅适用于 512 位向量或标量,并且仅适用于寄存器操作数。 (它将 3 个 EVEX 位重新用于设置向量长度(如果支持 AVX512VL),并区分广播内存操作数与向量。EVEX 位根据上下文重载以将更多功能打包到有限的 space 中。)
因此在 imm8 中拥有舍入控制使得vrndscaleps zmm0{k1}, [rdi]{m32bcst}, imm8
可以从内存广播一个浮点数,舍入它,并根据掩码寄存器将其合并到现有寄存器中k1
.所有这些都在一条指令中,假设它与 vroundps
相同,在 SKX 上解码为大约 3 微指令。 (http://agner.org/optimize/).