首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么样的GCC优化可以根据是否打印来改变双倍呢?

什么样的GCC优化可以根据是否打印来改变双倍呢?
EN

Stack Overflow用户
提问于 2018-06-11 11:16:42
回答 1查看 190关注 0票数 0

我正在调试实现一个算法的代码,其主循环在la s >= u || s <= l语句为true时终止,其中sul是在主循环中更新的doubles。在本例中,所有三个变量都在0.51.5之间。我不包括这里的代码,因为它不是我写的,提取一个MWE是困难的。我对代码在不同体系结构上的不同行为感到困惑,我希望下面的线索能够帮助我缩小算法中的错误。

一些浮点四舍五入似乎是错误的根本原因。到目前为止,我已经确定如下:

  • 该算法在x86-64上的所有优化级别上正确终止。
  • 该算法在-O3 (未尝试其他opt级别)的arm64、mips64和ppc64上正确终止。
  • 该算法与-O0在i686上正确终止。
  • 该算法在-O1、-O2和-O3上无限期地循环i686。
  • 主要问题:在算法无限期循环的情况下,在与lu进行比较之前,如果打印s (std::cout << s << std::endl),就可以正确终止。

在这里,什么样的编译器优化可能是相关的?

在GNU/Linux系统上对上述行为进行了观察,并在GCC 6.4、7.3和8.1中进行了复制。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-11 11:27:10

由于您说您的代码在x86-64和其他指令集上按预期工作,但在i686上中断,但只有在某些优化级别下,可能的罪魁祸首是x86扩展精度

在x86上,浮点指令存储比随后将这些值存储在内存中时更精确地存储寄存器。因此,当编译器可以重用已加载在寄存器中的相同值时,结果可能与必须保存和重新加载该值时不同。打印值可能需要保存和重新加载。

这是一个GCC名著“无虫”

GCC提供了一个-ffloat-store命令行选项,该选项可能会有所帮助:

-ffloat-store 不要将浮点变量存储在寄存器中,并禁止其他可能更改浮点值是从寄存器还是从内存中提取的选项。 此选项防止在机器上出现不必要的超额精度,例如68000,其中浮动寄存器( 68881)保持比双寄存器应有的更高的精度。同样,对于x86体系结构也是如此。对于大多数程序来说,过高的精度只会带来好的效果,但也有一些程序依赖于IEEE浮点的精确定义。在修改程序以将所有相关的中间计算存储到变量之后,对此类程序使用-ffloat-store

但是,正如前面提到的,它不会自动让代码与其他指令集的工作方式相同。您可能需要修改代码以显式地将结果存储在变量中。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50796496

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档