C ++:编译器是否优化整数+浮点算术运算?

时间:2018-03-11 21:34:01

标签: c++ optimization compilation floating-point integer

编译器是否有权甚至能够优化算术运算,其中一方是整数类型,而另一方是浮点数?或者,在100%的情况下执行操作之前,整数是否会被提升为浮点数?

我问的原因是因为我喜欢为了清晰起见而自己执行浮动促销,但如果它保留了编译器可以利用的情况,我可能会停止这样做。

2 个答案:

答案 0 :(得分:7)

如果编译器可以优化float和整数之间的加法,例如优化3.f + 14而不是在运行时执行加法,我会期望转换的存在对编译器是否可以优化没有影响。

这是一个基于现代编译器工作方式而非逻辑必然性的一般性陈述。在编译器认识到可以优化某些f + i的情况下,某些float f和某些整数i(可能是常量或表达式,而不仅仅是标识符),然后{ {1}}在编译器的分析中应该是等效的,并且应该接收相同的优化。

理解其原因的一种方法是,在解析f + (float) i时,编译器将识别出f + i必须转换为i,并且它将在其内部表示中构造程序,获取float的语句,获取f,将i转换为i,然后添加它们。在分析float时,将构造相同的内部表示,因此这两个语句将是等效的。

那就是说,我希望编译器可以优化的情况可能相当有限。编译器可以识别特定情况,例如添加两个常量,将f + (float) i零添加到整数,以及将整数0添加到float。有时编译器可能能够推导出floatf的值,即使它们是表达式或标识符,而不是常量,因为先前代码的流量必然产生一些值,然后它可能能够根据推导出的值进行优化。

因此,可以识别特殊情况。我不希望编译器通常能够将i转换为任何类型的优化比特,它比浮点数(或编译器通常使用的任何指令)更快。但是,从理论上讲,它可能会发生,如果是这样,设计良好的编译器应该优化f + if + i相同。 (也许有一些C实现在软件中支持浮点支持而不是硬件,它可以以比添加两个浮点值的更快的方式处理浮点值和整数的添加。)

答案 1 :(得分:2)

我很好奇,所以我做了一些快速测试,并且我观察到了以下行为:

这段代码的执行时间是:

for (int i = 0; i < 1000000000; ++i) {
    f = f + 1;
}
  • 没有-O2标志: 2156.25 ms
  • 使用-O2标志: 953.125 ms

通过浮动促销:

for (int i = 0; i < 1000000000; ++i) {
    f = f + (float)1;
}
  • 没有-O2标志: 2156.25 ms
  • 使用-O2标志: 968.75 ms

这只是一种情况。当然,这不是检查的最佳方式,我确信编译器可以根据情况做得更好或更差,但我观察到与O2优化的时间有点不同。

**在c ++ 11中运行。 CPU架构:AMD64 **