是否有(Linux)g ++等效于Visual Studio中使用的/ fp:precise和/ fp:fast标志?

时间:2010-07-13 03:42:06

标签: c++ visual-studio-2008 g++ compiler-optimization ubuntu-10.04

背景

许多年前,我继承了一个使用Visual Studio(VC ++)标志'/ fp:fast'的代码库,以便在特定的计算重量库中生成更快的代码。不幸的是,'/ fp:fast'产生的结果与不同编译器(Borland C ++)下的同一个库略有不同。当我们需要产生完全相同的结果时,我切换到'/ fp:precise',这很好,从那以后一切都很好。但是,现在我在uBuntu Linux 10.04上用g ++编译同一个库,我看到了类似的行为,我想知道它是否有类似的根本原因。我的g ++构建的数值结果与我的VC ++构建的数值结果略有不同。这让我想到了我的问题:

问题:

g ++与VC ++中的'fp:fast'和'fp:precise'选项有相同或类似的参数吗? (它们是什么?我想激活'fp:exact'等价物。)

更详细的信息:

我使用'make'编译,它调用g ++。据我所知(make文件有点神秘,而且不是我写的)g +调用中添加的唯一参数是“普通”(包括文件夹和要编译的文件)和-fPIC(我不确定这个开关是做什么的,我没有在'man'页面上看到它。

'man g ++'中唯一相关的参数似乎是打开优化选项。 (例如-funsafe-math-optimizations)。但是,我认为我没有打开任何东西,我只是想关闭相关的优化。

我尝试过发布和调试版本,VC ++为发布和调试提供了相同的结果,g ++给出了与发布和调试相同的结果,但是我无法获得g ++版本来提供与VC ++相同的结果版本

5 个答案:

答案 0 :(得分:18)

来自GCC manual

  

<强> -ffloat店内       不要将浮点变量存储在寄存器中,并禁止其他可能会改变浮点值是从寄存器还是内存中获取的选项。

     

这个选项可以防止诸如68000之类的机器上出现不希望的过度精度,其中浮动寄存器(68881)的精度比double应该具有的更高。同样适用于x86架构。对于大多数程序来说,多余的精度只会很好,但有些程序依赖于IEEE浮点的精确定义。在修改它们以将所有相关的中间计算存储到变量中之后,对这些程序使用-ffloat-store。

为了扩展一点,大多数这些差异来自于使用x86 80位浮点寄存器进行计算(相对于用于存储double值的64位)。如果中间结果保存在寄存器中而不写回存储器,则有效地在计算中获得16位额外的精度,使它们更精确,但可能与通过向存储器写入/读取中间值(或从只有64位FP寄存器的架构。)

这些标志(在GCC和MSVC中)通常强制将每个中间结果截断为64位,从而使计算对代码生成和优化以及平台差异的变幻莫测不敏感。除了精度/精度方面的成本之外,这种一致性通常还会带来轻微的运行时成本。

答案 1 :(得分:10)

过多的寄存器精度仅在FPU寄存器上存在问题,编译器(具有正确的使能开关)往往会避免。当在SSE寄存器中执行浮点计算时,寄存器精度等于存储器1。

根据我的经验,大多数/ fp:快速影响(和潜在的差异)来自编译器冒昧地执行代数变换。这可以像更改summands命令一样简单:

( a + b ) + c --> a + ( b + c)

可以 - 随意分配像*(b + c)这样的乘法,并且可以进行一些相当复杂的变换 - 所有这些都旨在重用以前的计算。 在无限精度中,这种变换当然是良性的 - 但是在有限的精度下,它们实际上改变了结果。作为玩具示例,尝试使用a = b = 2 ^( - 23),c = 1的summand-order-example.MS的Eric Fleegal describes it in much more detail

在这方面,最靠近/ fp:precise的gcc开关是-fno-unsafe-math-optimizations。我认为它默认是开启的 - 也许你可以尝试明确地设置它,看看它是否有所作为。类似地,您可以尝试显式关闭所有-ffast-math优化:-fno-finite-math-only,-fmath-errno,-ftrapping-math,-frounding-math和-fsignaling-nans(最后两个选项是< em>非默认!)

答案 2 :(得分:5)

我认为没有确切的等价物。您可以尝试-mfpmath=sse而不是默认-mfpmath=387来查看是否有帮助。

答案 3 :(得分:1)

这绝对与优化标志无关,假设“Debug”表示“优化关闭”。如果g ++在调试中给出与发布中相同的结果,那意味着它不是与优化相关的问题。 调试版本应始终将每个中间结果存储在内存中,从而保证与/ fp相同的结果:精确到MSVC。

这可能意味着其中一个编译器中存在(a)编译器错误,或者更可能是(b)数学库错误。我将在您的计算中深入研究各个函数,并缩小差异所在的位置。你可能会找到一个解决方法,如果你确实发现了一个错误,我相信相关的团队会喜欢听到它。

答案 4 :(得分:0)

-mpc32或-mpc64?

但您可能需要使用开关重新编译C和数学库以查看差异......这可能适用于其他人建议的选项。