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

背景:

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

Many years ago, I inherited a codebase that was using the Visual Studio (VC++) flag '/fp:fast' to produce faster code in a particular calculation-heavy library. Unfortunately, '/fp:fast' produced results that were slightly different to the same library under a different compiler (Borland C++). As we needed to produce exactly the same results, I switched to '/fp:precise', which worked fine, and everything has been peachy ever since. However, now I'm compiling the same library with g++ on uBuntu Linux 10.04 and I'm seeing similar behavior, and I wonder if it might have a similar root cause. The numerical results from my g++ build are slightly different from the numerical results from my VC++ build. This brings me to my question:

问题:

g++ 是否具有与 VC++ 中的 'fp:fast' 和 'fp:precise' 选项等效或相似的参数?(它们是什么?我想激活fp:precise"等价物.)

Does g++ have equivalent or similar parameters to the 'fp:fast' and 'fp:precise' options in VC++? (and what are they? I want to activate the 'fp:precise' equivalent.)

更多详细信息:

我使用调用 g++ 的make"进行编译.据我所知(make 文件有点神秘,不是我写的)添加到 g++ 调用的唯一参数是正常"参数(包括文件夹和要编译的文件)和 -fPIC(我不确定这个开关有什么作用,我在手册"页上没有看到它).

I compile using 'make', which calls g++. So far as I can tell (the make files are a little cryptic, and weren't written by me) the only parameters added to the g++ call are the "normal" ones (include folders and the files to compile) and -fPIC (I'm not sure what this switch does, I don't see it on the 'man' page).

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

The only relevant parameters in 'man g++' seem to be for turning optimization options ON. (e.g. -funsafe-math-optimizations). However, I don't think I'm turning anything ON, I just want to turn the relevant optimization OFF.

我尝试过发布和调试版本,VC++ 给出了相同的发布和调试结果,而 g++ 给出了相同的发布和调试结果,但我无法让 g++ 版本给出与 VC++ 相同的结果版本.

I've tried Release and Debug builds, VC++ gives the same results for release and debug, and g++ gives the same results for release and debug, but I can't get the g++ version to give the same results as the VC++ version.

推荐答案

寄存器精度过高只是 FPU 寄存器的问题,编译器(具有正确的启用开关)无论如何都倾向于避免这种情况.在SSE寄存器中进行浮点计算时,寄存器精度等于内存1.

Excess register precision is an issue only on FPU registers, which compilers (with the right enabling switches) tend to avoid anyway. When floating point computations are carried out in SSE registers, the register precision equals the memory one.

根据我的经验,大多数/fp:fast 影响(和潜在的差异)来自编译器随意执行代数变换.这可以像更改被加数顺序一样简单:

In my experience most of the /fp:fast impact (and potential discrepancy) comes from the compiler taking the liberty to perform algebraic transforms. This can be as simple as changing summands order:

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

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

can be - distributing multiplications like a*(b+c) at will, and can get to some rather complex transforms - all intended to reuse previous calculations. In infinite precision such transforms are benign, of course - but in finite precision they actually change the result. As a toy example, try the summand-order-example with a=b=2^(-23), c = 1. MS's 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(最后两个选项是 非默认!)

In this respect, the gcc switch nearest to /fp:precise is -fno-unsafe-math-optimizations. I think it's on by default - perhaps you can try setting it explicitly and see if it makes a difference. Similarly, you can try explicitly turning off all -ffast-math optimizations: -fno-finite-math-only, -fmath-errno, -ftrapping-math, -frounding-math and -fsignaling-nans (the last 2 options are non default!)

相关文章