双精度值存储更高的精度并且是浮点数的两倍,但英特尔 CPU 是否针对浮点数进行了优化?
也就是说,对于 +、-、\* 和 /,双精度运算是否与浮点运算一样快或更快?
64 位架构的答案会改变吗?
原文由 Brent Faust 发布,翻译遵循 CC BY-SA 4.0 许可协议
双精度值存储更高的精度并且是浮点数的两倍,但英特尔 CPU 是否针对浮点数进行了优化?
也就是说,对于 +、-、\* 和 /,双精度运算是否与浮点运算一样快或更快?
64 位架构的答案会改变吗?
原文由 Brent Faust 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
没有一个“英特尔 CPU”,特别是在哪些操作相对于其他人进行了优化方面!但其中大多数,在 CPU 级别(特别是在 FPU 内),都可以回答您的问题:
是“是” - 在 CPU 内,除了除法和 sqrt 之外 ,
double
比float
慢一些。 (假设您的编译器使用 SSE2 进行标量 FP 数学,就像所有 x86-64 编译器一样,以及一些 32 位编译器取决于选项。旧版 x87 在寄存器中没有不同的宽度,只有在内存中(它在加载/存储时转换),所以从历史上看,即使 sqrt 和除法对于double
也一样慢)。例如,Haswell 的
divsd
吞吐量为每 8 到 14 个周期 1 个(取决于数据),但divss
(标量单)吞吐量为每 7 个周期 1 个。 x87fdiv
是 8 到 18 个周期的吞吐量。 (来自 https://agner.org/optimize/ 的数字。延迟与除法的吞吐量相关,但高于吞吐量数字。)The
float
versions of many library functions likelogf(float)
andsinf(float)
will also be faster thanlog(double)
andsin(double)
,因为它们要正确的精度要少得多。他们可以使用较少项的多项式近似来获得float
与double
的完整精度_但是_,每个数字占用两倍的内存显然意味着 缓存上的负载更重,并且需要更多的内存带宽 来填充这些缓存行并将这些缓存行从/溢出到 RAM;您关心浮点运算性能的时间是在您执行 大量 此类运算时,因此内存和缓存考虑因素至关重要。
@Richard 的回答指出,还有其他方法可以执行 FP 操作( SSE / SSE2 指令;好的旧 MMX 仅限整数),特别适用于大量数据的简单操作(“SIMD”,单指令/多数据) 其中 每个向量寄存器可以打包 4 个单精度浮点数或仅 2 个双精度浮点数,因此这种效果会更加显着。
最后,您确实必须进行基准测试,但我的预测是,对于合理(即 大;-)基准,您会发现坚持单精度的优势(当然假设您 不需要 额外的精确!-)。