zr.*_*zr. 22 c math floating-point compiler-optimization
添加在数学上保持关联属性:
(a + b) + c = a + (b + c)
在一般情况下,此属性不适用于浮点数,因为它们表示有限精度的值.
作为优化的一部分,是否允许编译器在从C程序生成机器代码时进行上述替换?它在C标准中的确切位置在哪里?
chi*_*ill 14
不允许编译器执行"优化",这将导致计算的值不同于根据抽象机器语义计算的值.
5.1.2.3程序执行
[#1]本国际标准中的语义描述描述了抽象机器的行为,其中优化问题无关紧要.
[#3]在抽象机器中,所有表达式都按语义指定进行计算.
[#13]示例5由于精度和范围的限制,浮点表达式的重排通常受到限制.即使在没有溢出和下溢的情况下,由于舍入误差,实现通常也不能应用加法或乘法的数学关联规则,也不能应用分布规则.
在你的例子中:
(a + b) + c
甚至没有括号:
a + b + c
我们有
   +
  / \
  +  c
 / \
 a  b
并且编译器需要生成代码,就像a总结一样,b结果与之相加c.
您可以将浮点运算与gcc选项相关联:
-funsafe-math-optimizations -O2
例:
double test (double a, double b, double c) {    
  return (a + b + c) * (a + (b + c));
}
减少为:
double temp = a + (b + c);
return temp * temp;
类似地,(a + b + c) - (a + (b + c))减小到零,而忽略的可能性INF和NAN。
如果我-fassociative-math -O2改为使用它,则会收到奇怪的消息:
警告:-fassociative-math已禁用;其他选项优先
该-funsafe-math-optimizations能提高速度,如果你不关心操作数的顺序无论如何,但它可能会导致精度损失,如果操作数的顺序是非常重要的,你可能会失去NAN和INF结果。