斯威夫特的Double vs Float80速度

Spi*_*ngo 2 floating-point x86 x86-64 x87 swift

我听说x87 FPU可以使用80位浮点数,所以即使我想用64位数进行计算,它也会用80位计算它然后转换它.但是在x86-64上的Swift中最快,Double或者Float80(计算算术时)?

Cod*_*ray 6

虽然x87 FPU内部以80位"扩展"精度运行是正确的(至少,默认情况下;这是可自定义的,实际上是在macOS ABI设置64位内部精度之后的32位版本),针对x86的二进制文件-64不再使用x87 FPU指令.所有实现64位长模式扩展的x86芯片也支持SSE2(事实上,这是AMD64规范要求的),因此64位二进制文​​件始终可以支持SSE2.因此,这是用于实现浮点运算的,因为它更有效,更容易针对编译器进行优化.

即使是现代的32位版本,也只能将SSE2作为最低限度,当然在Macintosh平台上,因为SSE2是在Pentium 4中引入的,而Pentium 4早于Macintosh平台切换到Intel x86芯片.Apple机器中使用的所有x86芯片都支持SSE2.

所以不,通过使用80位扩展精度类型,您不会看到任何性能提升.您不会看到x87指令的任何性能改进,即使它们是由编译器生成的.而且你肯定不会在x86-64上看到任何性能提升,因为SSE2在硬件中支持最高64位精度.任何80位精度操作都必须在软件中实现,或强制智能编译器发出x87指令,这意味着您不会受益于SSE2的任何优秀功能和切实的性能改进.

  • 当然它包括它们,我没有暗示其他.我在这里概念性地使用x87 FPU,参考说明书.我认为措辞可能令人困惑.我使用术语"后退",因为编译器通常不会生成x87指令,因此它们被认为是过时的.硬件实际上如何实现这些指令是不相关的,或者至少我认为在这种情况下它并不相关.您可能会说在x86-64上看到软件实现的扩展双重计算是"荒谬的",但绝对*发生*. (3认同)

Ste*_*non 5

Double几乎总是[1]Float80在现代英特尔处理器上,几乎任何语言的速度都至少一样快。在某些情况下,它会明显更快:

  • Double使用更少的内存;算法的工作集可能在使用时适合缓存Double,但在使用时无法适合Float80,从而导致显着的性能风险。

  • Double可以利用 FMA 指令(在 Swift as.add[ing]Product(x,y)fma()free 函数中公开),这有效地将最近内核上可达到的浮点吞吐量加倍。

  • Double可以由编译器自动矢量化。上没有向量指令Float80。在可能的情况下,这可以使您获得高达 4 倍的加速。

  • sincospow等数学函数在 上Double比在 上快Float80

还有一些其他的使用原因Double:它可以移植到非 x86 硬件,而Float80不是,并且与 C 接口的互操作性Double比使用Float80. 您应该只Float80在必要时使用,Double否则默认使用。

[1] 有一些特殊情况Float80可以更快——例如,如果算法在 中反复下溢Double,但在 中保持在正常范围内Float80。这些很少见,通常不值得担心;更常见的是,您的算法也会在 中下溢Float80,只需稍后进行几次迭代即可。

  • 当然正确。我的意思是说我知道你在保持简单,但不小心忽略了这一点。我认为指出 80 位比 `double` 慢是有用的,即使两者都是用 x87 完成的,即使缓存未命中不是一个因素。明明是二等公民。 (2认同)