代码之家  ›  专栏  ›  技术社区  ›  Boinst

visualstudio中是否有一个(Linux)g++等价于/fp:precise和/fp:fast标志?

  •  11
  • Boinst  · 技术社区  · 16 年前

    许多年前,我继承了一个代码库,它使用visualstudio(VC++)标志'/fp:fast'在一个计算量很大的库中生成更快的代码。不幸的是,'/FP:FAST '产生的结果与不同编译器(Borland C++)下的同一库略有不同。由于我们需要产生完全相同的结果,我切换到'/fp:precise',它工作得很好,从那以后一切都很顺利。然而,现在我在ubuntulinux10.04上用g++编译同一个库,我看到了类似的行为,我想知道它是否有类似的根本原因。我的g++版本的数值结果与VC++版本的数值结果略有不同。这就引出了我的问题:

    问题:

    g++是否具有与VC++中的“fp:fast”和“fp:precise”选项相同或相似的参数(它们是什么?我要激活“fp:precise”等价项。)

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

    “mang++”中唯一相关的参数似乎是用来打开优化选项的(e、 g.—funsafe数学优化)。但是,我不认为我在打开任何东西,我只想关闭相关的优化。

    5 回复  |  直到 16 年前
        1
  •  10
  •   Community Mohan Dere    6 年前

    根据我的经验,大多数/fp:fast的影响(以及潜在的差异)来自于编译器自由地执行代数变换。这可以简单地更改summands顺序:

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

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

    在这方面,最接近/fp:precise的gcc开关没有不安全的数学优化。我认为它是默认开启的-也许你可以尝试显式设置它,看看它是否有区别。类似地,您可以尝试显式关闭所有-ffast数学优化:-fno finite math only、-fmath errno、-ftrapping math、-fronging math和-fsignaling nans(最后两个选项是 默认值!)

        2
  •  18
  •   Drew Hall    16 年前

    GCC manual

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

    此选项可防止在诸如68000这样的机器上出现不需要的多余精度,在这些机器上,(68881的)浮动寄存器保持的精度比双精度寄存器应该具有的精度高。x86体系结构也是如此。对于大多数程序来说,多余的精度只能起到很好的作用,但也有少数程序依赖于IEEE浮点的精确定义。对这些程序使用-ffloat store,修改它们后将所有相关的中间计算存储到变量中。

    为了扩展一个位,这些差异大多来自于使用x86 80位浮点寄存器进行计算(与用于存储的64位相比) double

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

        3
  •  5
  •   JSBÕ±Õ¸Õ£Õ¹    16 年前

    我认为没有确切的对等物。你可以试试 -mfpmath=sse -mfpmath=387 看看这是否有用。

        4
  •  1
  •   Drew Hoskins    16 年前

    调试构建应该始终将每个中间结果存储在内存中,从而保证与/fp:precise对MSVC的结果相同。

    这可能意味着(a)某个编译器中存在编译器错误,或者(b)更可能存在数学库错误。我将深入研究你计算中的各个函数,缩小差异所在。在那一点上,你可能会找到一个解决方法,如果你真的发现了一个bug,我相信相关的团队会很乐意听到的。

        5
  •  0
  •   Tomek    16 年前

    但是您可能需要用这个开关重新编译C和数学库来查看它们之间的区别。。。这可能也适用于其他建议的选项。