在GCC中启用严格浮点模式

在GCC中启用严格浮点模式,c,gcc,C,Gcc,我还没有创建一个程序来查看GCC是否需要它通过,当我创建时,我想知道如何启用严格浮点模式,这将允许在运行和计算机之间重现结果,谢谢。在支持它的Intel/AMD处理器上使用-msse2编译将使您几乎达到目的。不要让任何库将FPU置于FTZ/DNZ模式,您将大部分处于设置状态(尽管存在处理器错误) 对于其他体系结构,答案会有所不同。那些不提供任何方便的方法来获得准确的IEEE 754语义的架构(例如,SSE2 IA32 CPU之前的版本)将需要使用浮点仿真库来获得您想要的结果,但性能会受到很大的影

我还没有创建一个程序来查看GCC是否需要它通过,当我创建时,我想知道如何启用严格浮点模式,这将允许在运行和计算机之间重现结果,谢谢。

在支持它的Intel/AMD处理器上使用
-msse2
编译将使您几乎达到目的。不要让任何库将FPU置于FTZ/DNZ模式,您将大部分处于设置状态(尽管存在处理器错误)

对于其他体系结构,答案会有所不同。那些不提供任何方便的方法来获得准确的IEEE 754语义的架构(例如,SSE2 IA32 CPU之前的版本)将需要使用浮点仿真库来获得您想要的结果,但性能会受到很大的影响


如果目标体系结构支持
fmadd
(无中间舍入的乘法和加法)指令,请确保编译器在源代码中有显式乘法和加法时不使用该指令。除非您使用-ffast math选项,否则GCC不应该这样做。

如果您使用
-ffloat store
并始终将中间值存储到变量或将(显式)强制转换应用到所需的类型/精度,那么您应该至少达到目标的90%,甚至更多。我欢迎大家就这种方法是否仍有遗漏的情况发表意见。请注意,我声明,即使没有任何SSE选项,此选项也可以工作。

您也可以在i386/ia32目标上使用
GCC
的选项
-mpc64
,以强制进行双精度计算,即使在x87 FPU上也是如此。看


您还可以在运行时修改x87 FPU的行为,请参阅和。

注意,由于硬件中存在缺陷,即使强制严格模式也可能无法获得可复制的结果。这些事情真的发生了:,…@liori所说的“bug”,你的意思是“以一种众所周知且有文献记载的方式,仅提供比ieee754双精度更高的精度”。硬件没有bug。当然,它不能让编译器获得他们想要的干净的IEEE 754双精度语义,但这不是一个bug,只是一个错误。@liori我必须指出,在添加链接之前,我写了我的评论。有趣。我收回了我评论中的“硬件没有bug”部分。@Pascal Cuoq:是的,我实际上添加了链接,因为我认为有人会这样想:-)即使有硬件bug,我也不明白它如何支持“浮点不能给出可复制的结果”的位置。这只是意味着一些硬件坏了,不应该使用。您是否会因为f00f错误而声称x86锁前缀没有给出可复制的结果?不,您只需要将显示缺陷的CPU称为有缺陷的CPU……两个词:“双舍入”很好。就我个人而言,当我需要精确的浮点行为时,我只需对所有内容使用
long double
,这是一个很好的解决方案,但这样一来,您就无法在没有80位
long double
s的计算机上进行移植。现在我想起来了,我想知道OP所说的“计算机”是指跨体系结构,还是指一个给定体系结构中的跨处理器(在这种情况下,他应该是安全的)。避免双舍入问题的另一种方法是使用不同的舍入模式,例如
fesetround(FE_TOWARDZERO)
…-)值得一提的是,我发现GCC的
-fflotstore
与微软在
/fp:precise
模式下达成了一致。这是一件好事。@highscigue我说“差不多了”,因为-msse2的副作用是使编译器生成非严格的IEEE 754代码比生成严格的IEEE 754代码更困难,但并非不可能。编译器仍有可能努力打破浮点语义。举一个讽刺的例子,GCC开发人员可能会在某个版本中实现优化“将常数除法替换为倒数乘法”,然后有人可能会抱怨,这个特定的优化可能会移动到
-ffast math
选项。@highscigue总结一下,编译器制造商通常不太在意以书面形式提供这种保证,但在最好的情况下,如果您报告他们所做的更改违反了严格的IEEE 754语义,他们会倾听。结果可能取决于使用的编译器版本。最好的方法是使用
-S-msse2
并读取程序集以检查错误的转换。对于历史指令集,这有点没有希望:可以在中找到一些详细信息。您可能还希望查看编译器将宏
FLT\u EVAL\u方法设置为的值。此宏由编译器设置。另请参见
FP_CONTRACT
(由程序员设置)。@PascalCuoq:我希望语言包含不同的严格和非严格运算符,因为许多算法需要使用严格的语义执行一些关键步骤,但在其他步骤中可以容忍更松散的语义[例如,因为一个步骤上的+/-1lsb错误将在下一个步骤中被取消]。如果一个算法中25%的步骤需要精确,那么最好调用这25%并让其他操作运行得更快,而不是让所有操作都运行得慢一些。@supercat作为一个对浮点不感兴趣的人,他上个月第一次写了一个数值稳定的算法,实际上他希望编译器重新运行我完全同意FMA的ce乘法和加法。据我所知,GCC仍然不允许以低于编译单元的比例选择一种或另一种模式。特别是“确定性跨平台”的文章非常棒。谢谢!