我在Delphi中拥有相同数量的运算源代码,它被编译为32位和64位应用程序。从日志文件中我可以看到数字略有不同(1e-14相对误差)。所以我想知道在运行32位和64位代码时,同一CPU是否可能以不同方式执行浮点运算。或者它是编译器负责的东西。
答案 0 :(得分:7)
我将假设代码没有明确使用Extended
。由于该数据类型在32位和64位之间不同(32位为10位,64位为8位),因此Extended
的任何显式使用都会产生直接的差异。我将假设您使用Double
表示所有变量。虽然下面的论点平等转移到Single
。
除此之外,最常见的原因是两个浮点单元之间的行为差异。
由32位代码使用的x87单元将中间值存储为80位扩展精度。由64位代码使用的SSE单元将中间值存储为64位双精度。
现在,可以使用控制字配置x87单元,将中间值存储为64位精度。它在性能方面没有任何区别,但会使您的32位和64位结果更接近。
即使这样,你也不会在不同的单位上获得完全相同的结果。事实上,你不会在所有x87单位上得到完全相同的结果。尽管这些单元都符合IEEE754标准,但该标准允许一定程度的计算余地。
更重要的是,在32位和64位之间执行高阶计算,如三角函数,对数,取幂等。 32位单元具有比64位单元更多的内置功能。您将在Delphi源代码中注意到,例如,trig函数都是在RTL中为64位实现的。在32位代码上,它们通过调用x87 ops实现。
最重要的是,当涉及浮点计算时,您永远不会让32位和64位程序完全一致。你必须接受差异才能达到很小的容忍度。
答案 1 :(得分:3)
Extended
等于Double
。 X32模式使用FPU浮点单元,而X64使用SSE寄存器进行浮点执行。
还有编译器指令Floating point precision control (Delphi for x64)
,默认情况下是打开并将中间单个浮点数保持为双精度。