【问题标题】:Extent of G++ compiler optimization on non-commutative operationsG++ 编译器对非交换操作的优化程度
【发布时间】:2015-07-06 22:39:45
【问题描述】:

我担心 G++ 优化器对算术运算的影响,特别是不一定可交换的整数运算,例如 * 和 /。当我查看 gdb 中使用 -O3 标志集编译的一个简单函数时,就产生了这种担忧。总而言之,这是一个更好的功能,但它的形式与没有优化时的形式完全不同,操作已被删除,并且一些已被重新定位。这是一个简单的函数,我将用它来展示我关注的症结;

int ClipLower(int num, int dig){
  int Mult10 = 1;
  while (dig != 0){
    Mult10 *= 10, dig--;
  }
  return ((num / Mult10) * Mult10);
}

这个函数只是剪掉数字'dig'下面的base10数字。我担心的是,编译器是否考虑了整数数学是不可交换的事实?那么,编译器是否会尝试将 (num / mult10) * mult10 减少为 num * 1,当然丢弃那个?

我知道 volatile 会避免这种情况,但我仍然希望尽可能优化我的代码。所以本质上我是在问 gnu 优化器是否会理解整数数学是非交流性的,并且更进一步的问题是优化问题到底有多少。

还有

这里是-O4处函数的反汇编,如你所见,操作顺序很好

  13        return ((num / Mult10) * Mult10);
       cltd
       idiv   %ecx
       imul   %ecx,%eax
       ret

有趣的是,编译器在函数之后生成了大量无操作,可能是填充,因为它最终太小了。

【问题讨论】:

  • 请注意,标题中的 volatile 不是指关键字,而只是指 volatile 的操作。
  • 不允许编译器进行优化,因为它会改变输出。但如果您打开-ffast-math,它可能会针对浮点执行此操作。
  • 我相信这个词是 commutative 而不是 communicative。后者是关于交流,而第一个是处理表达式的定位和评估。
  • @ThomasMatthews 我会做出改变的,谢谢你的提示
  • @Mysticial 谢谢你的信息,很高兴知道优化器有一定的长度

标签: c++ g++ compiler-optimization


【解决方案1】:

这是 g++ 中-O3 等价的标志列表:https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

现在如果你仔细看,还有-Ofast,它被定义为-O3 + 其他一些,尤其是-ffast-math。在-ffast-math 的描述中,您可以阅读:

除 -Ofast 之外的任何 -O 选项都不会打开此选项,因为它可能导致依赖于数学函数的 IEEE 或 ISO 规则/规范的精确实现的程序的错误输出。但是,对于不需要这些规范保证的程序,它可能会产生更快的代码。

这样做是为了确保默认编译器标志不违反舍入误差和其他浮点标准规范。

关于SO还有一个相关的问题,编译器为什么不把a*a*a*a*a*a优化成(a*a*a)^2,答案是一样的。 (我找不到链接 atm =/)

顺便说一句,Mult10 *= 10, dig--; 你想失去关注你代码的人吗? =D

编辑: 顺便说一句,经过-O3 没有任何效果。除了有些人说你可能会溢出一些内部变量。我没有测试溢出,但我确定 -O4-O100 在撰写本文时等同于 -O3

【讨论】:

  • 回想起来,我可能应该只使用一个 for 循环,可能是这样的:P for(int i = 0; i
  • 老实说,我很想尝试使用 -O4 进行编译,看看会发生什么。感谢您分享此内容,我必须先查看该网页,然后再询问任何包含问题的进一步文档
  • 我主要指的是逗号运算符。我很确定有相当多的人会在这一点上迷路。
  • 因为他们可能认为我已经超载了它?或者他们可能不知道运营商的广泛而多样的应用程序?
【解决方案2】:

试试看组装

优化不应该影响输出,只影响速度。应保持四舍五入。但是可能会出现错误,尽管现在已经很少见了。

通常问题更可能与浮点有关。 2/7 与 floats 可能略有不同。

对于ints,无论进行何种优化,它都应该始终为 0,即使乘以 7。

【讨论】:

    猜你喜欢
    • 2012-02-12
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 2020-01-09
    相关资源
    最近更新 更多