我听说x87 FPU可以使用80位浮点数,所以即使我想用64位数进行计算,它也会用80位计算它,然后转换它。但是在 x86-64 ,Double
或Float80
(计算算术时)中Swift最快?
答案 0 :(得分:6)
虽然x87 FPU内部以80位“扩展”精度运行是正确的(至少,默认情况下;这是可自定义的,实际上是在macOS ABI设置64位内部精度之后的32位构建), 定位x86-64的二进制文件不再使用x87 FPU说明。所有实现64位长模式扩展的x86芯片也支持SSE2(事实上,这是AMD64规范要求的),因此64位二进制文件始终可以支持SSE2。因此,这是用于实现浮点运算的,因为它更有效,更容易针对编译器进行优化。
现代时代的32位版本甚至假设SSE2为最低版本,而Macintosh平台上的肯定是,因为SSE2是在Pentium 4上引入的,早于Macintosh平台切换到Intel x86芯片。 Apple机器中使用的所有x86芯片都支持SSE2。
所以不,通过使用80位扩展精度类型,您不会看到任何性能提升。您不会看到x87指令的任何性能改进,即使它们是由编译器生成的。并且你当然不会在x86-64上看到任何性能提升,因为SSE2在硬件中支持最高64位精度。任何80位精度操作都必须在软件中实现,或强制智能编译器发出x87指令,这意味着您不会受益于SSE2的任何优秀功能和切实的性能改进。
答案 1 :(得分:3)
Double
几乎总是[1]在现代英特尔处理器上的Float80
上几乎与所有语言一样快。在某些情况下,它会明显加快:
Double
使用更少的内存;使用Double
时,算法的工作集可以适应缓存,但在使用Float80
时却无法适应,从而导致严重的性能危害。
Double
可以利用FMA指令(在Swift中显示为.add[ing]Product(x,y)
和fma()
免费功能),这有效地使最近核心上可达到的浮点吞吐量加倍
Double
可以由编译器自动矢量化。 Float80
上没有向量说明。如果可能,这可以为您提供高达4倍的加速。
sin
,cos
,pow
等数学函数在Double
上比在Float80
上更快。
使用Double
还有其他一些原因:它可以移植到非x86硬件,而Float80
不可移植,Double
可以更轻松地与C接口实现互操作而不是Float80
。您应该只在必要时使用Float80
,否则默认使用Double
。
[1]有一些利基案例,Float80
可以更快 - 如果算法在Double
中重复下溢,但在Float80
中保持在正常范围内。这些是罕见的,通常不值得担心;更常见的是,您的算法也会在Float80
中下溢,稍后再进行几次迭代。