浮点运算32位模式vs 64位模式



我在Delphi中有相同的数字运算源代码,它被编译为32位和64位应用程序。从日志文件中,我可以看到数字略有不同(相对误差为1e-14)。所以我想知道是否有可能相同的CPU在运行32位和64位代码时执行不同的浮点操作。

我将假设代码没有显式地使用Extended。由于该数据类型在32位和64位之间不同(32位为10字节,64位为8字节),因此任何显式使用Extended都会立即引入差异。我假设所有的变量都用Double。尽管下面的论点同样可以转移到Single

除此之外,最常见的原因是两个浮点单位的行为不同。

32位代码使用的x87单元将中间值存储到80位扩展精度。SSE单元,由64位代码使用,存储64位双精度的中间值。

现在,x87单元可以配置使用控制字来存储64位精度的中间值。它在性能方面没有区别,但会使32位和64位的结果更接近。

即使这样,你也不会在不同的单位上得到完全相同的结果。事实上,您不会在所有x87单元上得到完全相同的结果。尽管这些设备都符合IEEE754标准,但该标准允许一定程度的计算余地。

更重要的是,高阶计算,如三角函数、对数、幂等,在32位和64位之间的执行方式完全不同。32位单元比64位单元具有更多的内置功能。在Delphi源代码中您会注意到,例如,三角函数都是在64位RTL中实现的。在32位代码上,它们通过调用x87操作来实现。

底线是,当涉及浮点计算时,您将永远无法使32位和64位程序完全一致。

Extended等于X64中的Double。X32模式使用FPU浮点单元,而X64模式使用SSE寄存器执行浮点。

还有编译器指令Floating point precision control (Delphi for x64),默认情况下是on的,并将中间单浮点数保持为双浮点数。

最新更新