我们正在编写一个仿真器,并且想知道对于给定的 FPU 状态,在运行 FPU 指令后,FPU 的状态是确定性的,例如。FDIV?
有许多实现 x87 指令集的 Intel 兼容 CPU 架构。在测试 FPU 仿真的正确性时,我们是否应该依赖最终的 CPU 状态?
不同的实现是否以不同的方式循环/计算?
我们正在编写一个仿真器,并且想知道对于给定的 FPU 状态,在运行 FPU 指令后,FPU 的状态是确定性的,例如。FDIV?
有许多实现 x87 指令集的 Intel 兼容 CPU 架构。在测试 FPU 仿真的正确性时,我们是否应该依赖最终的 CPU 状态?
不同的实现是否以不同的方式循环/计算?
是的,x87 FPU 对于基本操作+
、-
、*
、/
、是确定性的sqrt
。例如,在其默认状态下(全宽有效数和舍入到最近偶数模式), 的结果恰好是与 和 的数学和x + y
的结果最接近的可表示的 80 位浮点值。x
y
兼容芯片的制造商已经对上述操作实施了完全相同的定义。
在纯 CISC 传统中,x87 的指令集还包含用于计算数学函数的高级指令,例如,正弦 ( FSIN
) 的近似值。这些指令的结果因处理器品牌和型号而异。在您的模拟器中,您可能只需要提供与仍在使用的这些指令的最差实现之一一样好的东西。如果您使用宿主语言的数学库中的函数结果,没有人应该抱怨sinl()
,这通常比FSIN
(通过显式参数缩减和多项式逼近实现,而不是调用FSIN
)。
如果您坚持基本的 FPU 指令,并且如果您希望它们产生一致的结果,则应该为您的 FPU 算法使用相同的编译器。这还不包括您需要正确初始化 FPU 库的事实。
如果您有兴趣,这里有一些关于这个主题的好读物:https ://randomascii.wordpress.com/2013/07/16/floating-point-determinism 。
这篇文章中其他文章的链接非常有用。
正如其他人所说,基本的五个操作将在所有 x87 FPU 上给出相同的结果。然而...
x87 FPU 很特别。它是 80 位寄存器意味着它可能会得到与任何其他 FPU 不同的结果(例如在具有 64 位浮点寄存器的 PowerPC 或 ARM 上)。这些结果可能更好或更差。即使将 x87 舍入模式设置为 32 位或 64 位,也不会使其与 PowerPC/ARM 相同,因为指数仍然是无界的。
对于编写模拟器,这无关紧要,只是这意味着您不一定要使用主机 FPU 来模拟 x87 FPU。我在这两篇文章中讨论了许多这些问题:
http://randomascii.wordpress.com/2013/07/16/floating-point-determinism http://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/