【发布时间】: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