我有一个用C ++编写的高精度ODE(常微分方程)求解器。我使用用户定义的类型real_type
进行所有计算。在标题中有一个typedef声明此类型:
typedef long double real_type;
我决定将long double类型更改为__float128
以获得更高的准确性。除此之外,我还包括quadmath.h
,并用libquadmath替换了所有标准数学函数。
如果"长双"在没有任何优化标志的情况下构建版本,一些参考ODE在77秒内解决。如果使用-O3标志构建此版本,则在25秒内解决相同的ODE。因此-O3标志加速计算三次。
但在" __浮动128"没有标志的版本类似ODE在190秒内解决,而-O3在160秒内解决(约15%的差异)。为什么-O3优化会对四倍精度计算产生如此微弱的影响?也许我应该使用其他编译器标志或包含其他库?
答案 0 :(得分:2)
编译器优化的工作方式如下:编译器识别代码中的某些模式,并用等效但更快的版本替换它们。如果不确切知道代码是什么样的以及编译器执行了哪些优化,我们就不能说编译器缺少什么。
可能是编译器知道如何对本机浮点类型及其操作执行的几个优化,它不知道在__float128和操作的库实现上执行。它可能无法识别这些操作。也许它无法查看库实现(您应该尝试与您的程序一起编译库并启用链接时优化)。
答案 1 :(得分:0)
相同的优化提供了基本相同的好处。百分比下降只是因为数学本身需要更长的时间。
要相信优化应该是相同的百分比,你必须相信让数学花费更长的时间会使优化器找到更多的节省。你为什么这么想?
答案 2 :(得分:0)
如果你的目标是x86架构,那么在GCC中__float128
是一个实际的四倍精度FP类型,而long double
是x87 96位FP类型(双重扩展)。
使用较小精度类型的数学比使用较大精度类型的数学运算更快是合理的。使用本机硬件类型的数学比使用非本机类型的数学更快也是合理的。