64位编译器中的浮点数支持

10

64位Delphi编译器的浮点支持会有哪些预期表现?

  • 64位编译器是否会使用SSE来实现浮点运算?

  • 64位编译器是否支持当前的80位浮点类型(Extended)?

这些问题密切相关,因此我将它们作为一个问题提出。


我知道我读过这个,但不太记得在哪里看到的。 - Andreas Rejbrand
可能是如何为潜在的64位编译器准备我的32位Delphi程序?的重复问题。 - Gregor Brandt
3
每一个关于Delphi 64位的新问题都应该被关闭为完全重复吗? - Andreas Rejbrand
1
我必须说,如果放弃对80位浮点数值的支持,那对我来说将是非常糟糕的消息。即使人们实际上并不需要这种精度,这也可能会给他们带来各种头痛,因为程序(数值结果)在32位和64位程序之间可能会表现出不同的行为。 - PhiS
6个回答

5
我在这个主题上发了两篇文章(这里那里),总结一下,是的,64位编译器使用SSE2(双精度),但不使用SSE(单精度)。所有内容都转换为双精度浮点数,并使用SSE2进行计算(编辑:但是有一个选项来控制它)。
这意味着,如果双精度浮点数上的数学运算很快,那么单精度浮点数上的数学运算就会很慢(会产生大量冗余的单精度和双精度之间的转换),“扩展”被别名为“双精度”,中间计算的精度被限制为双精度。 编辑:当时有一个未记录的指令,可以控制SSE代码生成,{$EXCESSPRECISION OFF} 激活SSE代码生成,将性能恢复到预期水平。

3
根据Marco van de Voort在他的回答中提到的:如何为可能的64位编译器准备32位Delphi程序

x87 FPU在x64上已经被弃用,通常情况下,SSE2将用于浮点数。因此,浮点数及其异常处理可能会有所不同,并且扩展可能没有80位(而是64位或更少可能是128位)。这也涉及到通常的舍入(协处理器控制工作)的更改,当与期望不同的fpu word的C代码进行接口时。

PHis在评论中说:

我不会说x87 FPU已经被弃用,但很明显微软已经决定尽最大努力使其成为弃用状态(并且他们似乎真的不喜欢80位FP值),尽管在Win64上使用FPU / 80位浮点数显然是技术上可行的。


FPU最初在x86_64上被微软弃用(XP64),据我所知,它的上下文甚至没有保存在最初的XP64版本中。这个问题后来得到了解决,但它仍然是被弃用的。 - Marco van de Voort
@Marco - 请注意,一些编译器(例如英特尔的C++编译器)可以为x64生成x87 FPU的代码。此外,微软的64位宏汇编器也支持FPU指令集。因此,似乎更多的是微软不想使用x87代码(例如VC++),但操作系统确实支持它。 - PhiS
据我所知,在x86_64 API中已经被弃用。当32位操作系统(和应用程序?)真正过时时,它可能会被淘汰。 - Marco van de Voort
@Marco - 嗯,我持怀疑态度;我们拭目以待。Win32 API是否真的有使用80位浮点数的情况(不考虑返回值在ST(0)中的情况,这些可以是任何你想要的)?如果没有,那么同样的API显然不需要在x64上使用x87 FPU,因为你至少有SSE2。(但这并不意味着程序不能在内部使用x87。) - PhiS
据我所知不支持,因为Windows NT旨在可移植并支持其他目标(如sparc、powerpc和IA64),而这些目标不支持extended。 - Marco van de Voort

3

我刚才回答了你的另一个问题,但是我认为它实际上应该放在这里:

显然,在产品发布之前,除了Embarcadero没有人能够确定地回答这个问题。

任何好的x64编译器都很可能将SSE2指令集作为基线,并因此尽可能使用SSE功能进行浮点运算,最小化使用x87 FPU。然而,也应该说,没有技术原因会阻止在x64应用程序代码中使用x87 FPU(尽管有关此事的谣言已经存在了一段时间;如果您想要更多信息,请查看Agner Fog的调用约定手册,特别是第6.1章“64位Windows中可以使用浮点寄存器吗?”)。

编辑1:Delphi XE2 Win64确实不支持80位浮点计算(例如,参见这里的讨论(尽管允许读/写这样的值)。可以使用记录+类操作符将这样的功能带回Delphi Win64,就像这个TExtendedX87类型中所做的那样(尽管有警告)。


2

在 Embarcadero 真正发布 64 位 Delphi 编译器之前,我们不会确切知道它如何实现浮点运算。在此之前的任何推测都只是猜测。但一旦我们确切知道了,要想改变已经为时已晚。

Allen Bauer 的推文似乎表明他们将使用 SSE2,并且 Extended 类型可能会从 80 位减少到 64 位。我认为这是一个坏主意,因为有很多原因。我已经在 QualityCentral 报告中写下了我的想法 Extended should remain an 80-bit type on 64-bit platforms

如果您不希望在转换到 64 位 Delphi 后,代码从 80 位精度降至 64 位精度,请单击 QualityCentral 链接并投票支持我的报告。投票越多,Embarcadero 越可能会听取意见。如果他们确实使用 SSE2 进行 64 位浮点运算(这是有道理的),那么使用 FPU 添加 80 位浮点运算将是 Embarcadero 的额外工作。除非有很多开发人员要求,否则我怀疑他们会这样做。


感谢QC报告,非常感激。 - PhiS

2

对于double=extended位:

请阅读ALlen Bauer的Twitter账户Kylix_rd:

http://twitter.com/kylix_rd

从逻辑上讲,这是合理的,因为虽然SSE2寄存器是128位,但它们被用作两个64位的双精度浮点数。


但是对于不适合寄存器的其他类型,情况也是一样的:调用约定允许通过引用传递它们。 - PhiS
整数通常具有比ALU更高精度的一种类型。(32位->int64,64位->int128),这与整数的某些属性有关。然而,对于浮点数通常不是这种情况。 x87 CPU支持扩展作为最高级别,但是Delphi不支持更多。通过引用传递(例如作为具有两个双精度的记录)可以解决数据传输的问题,但不能进行计算,这将是软浮点运算并非效率很低。请记住,Int64部分由CPU加速。 - Marco van de Voort

1

谢谢Jeroen--我已经添加了一个指针,希望它有所帮助。 - PhiS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接