"fixing up" 浮动是什么意思?

What is meant by "fixing up" floats?

我正在查看 AVX-512 中的指令集并注意到一组 fixup 指令。一些 examples:

_mm512_fixupimm_pd, 
_mm512_mask_fixupimm_pd, 
_mm512_maskz_fixupimm_pd

_mm512_fixupimm_round_pd, 
_mm512_mask_fixupimm_round_pd, 
_mm512_maskz_fixupimm_round_pd

这里的"fixing up"是什么意思?

这是一个很好的问题。英特尔的答案(我的粗体)在这里:

This instruction is specifically intended for use in fixing up the results of arithmetic calculations involving one source so that they match the spec, although it is generally useful for fixing up the results of multiple-instruction sequences to reflect special-number inputs. For example, consider rcp(0). Input 0 to rcp, and you should get INF according to the DX10 spec. However, evaluating rcp via Newton-Raphson, where x=approx(1/0), yields an incorrect result. To deal with this, VFIXUPIMMPS can be used after the N-R reciprocal sequence to set the result to the correct value (i.e. INF when the input is 0).

在以下位置寻找 VFIXUPIMMPD:

https://software.intel.com/sites/default/files/managed/0d/53/319433-022.pdf

Intel 在他们的 "future extensions" instruction set reference manual 中的描述有通常的 Operation 部分,它完全指定了哪些位去哪里。

Intrinsics Guide 还重现了 Operation 部分,这是对内在函数指南中其他一些记录不佳的条目的一个很好的更改。或者它可能是最近添加的。它仍然遗漏了 table 和图表。我通常发现 insn ref 手册更有用,除了有时在搜索我可能没有想到或不知道的说明时。

该指令的操作部分冗长且难以理解,英文文本描述只是一个粗略的摘要:

Perform fix-up of quad-word elements encoded in double-precision floating-point format in the first source operand (the second operand) using a 32-bit, two-level look-up table specified in the corresponding quadword element of the second source operand (the third operand) with exception reporting specifier imm8

...

The two-level look-up table perform a fix-up of each DP FP input data in the first source operand by decoding the input data encoding into 8 token types. A response table is defined for each token type that converts the input encoding in the first source operand with one of 16 response actions.

预期用例是:

  • dest=rcppd(或类似)+ newton-raphson 迭代的结果
  • src=近似+细化的输入
  • table=修正 table。可以是广播内存操作数,因此在您希望向量的每个元素都具有相同 table 的常见情况下,只需要 64 或 32 位内存。 (table 对于单精度和双精度都只有 32b,但是 DP 版本的广播选项是 m64bcst。它的高 32 位是垃圾是可以的,但它不能跨越页面边界进入未映射的page:这可能会出错。)

也许更详细的英文描述有助于弥合非常粗略的摘要和完整伪代码之间的差距:

对于每个 src 元素:

  • tsrc = 如果设置了 MXCSR.DAZ,则将非正规化刷新为零。原始 src 在此之后根本没有使用:没有 dest=src 操作,只有 dest=tsrc.

  • tsrc 归类为八种 "token" 类型之一(QNAN、SNAN、零、+1、-Inf、+Inf、负值、正值)。如果imm8不为零,则在找到匹配类型的token时会触发异常。

  • 使用该类别标记在第三个操作数的相应元素中查找操作(这是一个 table 八个 4 位代码,每个标记一个)。

  • action可以是dest=dest, dest=tsrc, dest=NaN, dest=+/-Inf, dest=Inf with the sign of tsrc, dest=+/-0之一, dest=+/-1, dest=1/2, dest=90.0, dest=pi/2, 或 dest=MAX/MIN_FLOAT。请参阅英特尔文档,了解哪些代码映射到哪些操作。

这个过程是针对每个矢量元素单独完成的。

典型的用法是将 dest=dest 代码用于我们正在修复的结果已经正确的所有情况。请注意,dest 也是一个输入操作数,即使没有写掩码,因为 dest=dest 操作。