【问题标题】:Enabling strict floating point mode in GCC在 GCC 中启用严格的浮点模式
【发布时间】:2011-11-09 21:14:59
【问题描述】:

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

【问题讨论】:

  • 请注意,由于硬件中的错误,即使强制执行严格模式也可能无法为您提供可重现的结果。这些真的发生了:cs.earlham.edu/~dusko/cs63/fpu.htmllwn.net/Articles/89586reghardware.com/2006/04/28/amd_opteron_fpu_bug...
  • @liori “错误”是指“仅以众所周知且记录在案的方式提供比 IEEE 754 双精度更高的精度”。硬件没有错误。它不会让编译器获得他们想要的干净的 IEEE 754 双精度语义,当然,但这不是错误,只是功能错误。
  • @liori 我必须指出,我在您添加链接之前写了我的评论。有趣的。我撤回评论中的“硬件没有错误”部分。
  • @Pascal Cuoq:是的,我实际上添加了链接,因为我认为有人会这样想 :-)
  • 即使有硬件错误,我也看不出它如何支持“浮点不给出可重现的结果”的位置。这只是意味着某些硬件已损坏,不应使用。由于 f00f 错误,您会声称 x86 锁定前缀不会给出可重现的结果吗?不,您只需调用表现出错误缺陷的 cpus...

标签: c gcc


【解决方案1】:

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

您还可以在运行时修改 x87 FPU 行为,请参阅 Deterministic cross-platform floating point arithmeticsAn Introduction to GCC

【讨论】:

  • “确定性跨平台”文章尤其出色。谢谢!
【解决方案2】:

在支持它的 Intel/AMD 处理器上使用 -msse2 进行编译将使您几乎实现目标。不要让任何库将 FPU 置于 FTZ/DNZ 模式,您将基本完成设置(尽管存在处理器错误)。

对于其他架构,答案会有所不同。那些不提供任何方便的方法来获得精确的 IEEE 754 语义的架构(例如,SSE2 之前的 IA32 CPU)将需要使用浮点仿真库来获得您想要的结果,但性能损失非常高。

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

【讨论】:

  • @highsciguy 我说“差不多了”是因为 -msse2 的副作用是让编译器生成非严格的 IEEE 754 代码比生成严格的 IEEE 754 代码更难,但并非不可能IEEE 754 代码。编译器仍有可能努力破坏浮点语义。举个讽刺的例子,GCC 开发人员可能会在某些版本中实现“将除法替换为乘以倒数”的优化,然后有人可能会抱怨,并且此特定优化可能会移至 -ffast-math 选项。
  • @highsciguy 总而言之,编译器制造商通常不会在意以书面形式提供这种保证,但在最好的情况下,如果您报告他们所做的更改违反了严格的 IEEE 754,他们会倾听语义。结果可能取决于一个正在使用的精确编译器版本。最好的办法是使用-S -msse2 并阅读程序集以检查不正确的转换。有了历史指令集,就有些无望了:有些细节可以看gcc.gnu.org/ml/gcc-patches/2008-11/msg00105.html
  • 您可能还想查看编译器将宏 FLT_EVAL_METHOD 设置为的值。该宏由编译器设置。另见FP_CONTRACT(由程序员设置)。
  • @PascalCuoq:我希望语言包含不同的严格和非严格运算符,因为许多算法需要一些关键步骤才能以严格的语义执行,但在其他步骤中可以容忍更宽松的语义[例如因为一个步骤上的 +/- 1lsb 错误将在下一步中被取消]。如果算法中 25% 的步骤需要精确,最好调出这 25%,让其他操作运行得更快,而不是一切都运行缓慢。
  • @supercat 作为对浮点数不感兴趣的人,他第一次写了一个数值稳定的算法,他实际上希望编译器用 FMA 替换乘法和加法,我完全同意。据我所知,GCC 仍然不允许以低于编译单元的比例选择一种模式。
【解决方案3】:

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

【讨论】:

  • 两个字:“双舍入”exploringbinary.com/…
  • 好点。就个人而言,当我需要精确的浮点行为时,我只使用long double 来处理所有事情......
  • 这是一个很好的解决方案,但是您不再可以在没有 80 位 long doubles 的计算机之间移植。现在我想起来了,我想知道当他说“计算机”时,OP 是否真的意味着跨架构,或者只是跨给定架构内的处理器(在这种情况下,他应该是安全的)。
  • 另一种避免双舍入问题的方法是使用不同的舍入模式,例如fesetround(FE_TOWARDZERO)... :-)
  • 不管怎样,我发现-ffloat-store with GCC 在/fp:precise 模式下与微软达成一致。这是一件好事。
猜你喜欢
  • 1970-01-01
  • 2020-11-09
  • 2022-01-15
  • 2022-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-07
  • 2021-02-24
相关资源
最近更新 更多