4

I have the same number crunching source code in Delphi which is compiled both as 32 bit and as 64 bit application. From the log file I can see that the numbers are slightly (1e-14 relative error) different. So I'm wondering if it is possible that the same CPU performs floating point operations differently when running 32 bit and 64 bit code. Or is it something that the compiler is responsible for.

4

2 回答 2

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 源代码中注意到,例如,三角函数都是在 64 位的 RTL 中实现的。在 32 位代码上,它们是通过调用 x87 操作来实现的。

最重要的是,当涉及浮点计算时,您永远不会让您的 32 位和 64 位程序完全一致。您将不得不接受小范围内的差异。

于 2013-06-11T12:10:32.167 回答
3

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

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

于 2013-06-11T11:51:56.620 回答