简体   繁体   English

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

[英]C++: Do compilers optimize integer + float arithmetic operations?

Are compilers empowered or even capable of optimizing arithmetic operations where one side is an integer type, while the other is a float? 当一侧为整数类型而另一侧为浮点数时,编译器是否被授权甚至具有优化算术运算的能力? Or will the integer just be promoted to a float before performing the operation in 100% of the cases? 还是在100%的情况下在执行操作之前将整数提升为浮点数?

The reason I ask is because I like to perform the float promotion myself for clarity, but I might stop doing so if it preserves a situation the compiler can capitalize on. 我问的原因是因为我为了清楚起见喜欢自己执行浮点升级,但是如果它保留了编译器可以利用的情况,我可能会停止这样做。

In cases where a compiler can optimize an addition between a float and an integer, such as optimizing 3.f + 1 to 4 rather than performing the addition at run-time, I would expect the presence of a cast to have no effect on whether the compiler can optimize. 如果编译器可以优化float与整数之间的加法,例如优化3.f + 14而不是在运行时执行加法,则我期望强制转换的存在对是否是否有影响没有影响。编译器可以优化。

This is a general statement, based upon how modern compilers work, not a logical necessity. 这是一个一般性声明,基于现代编译器的工作方式,而不是逻辑上的必要性。 In circumstances where a compiler recognizes that some f + i can be optimized, for some float f and some integer i (possibly constants or expressions, not just identifiers), then f + (float) i should be equivalent in the compiler's analysis and should receive the same optimization. 在编译器认识到某些f + i可以被优化的情况下,对于一些float f和一些整数i (可能是常量或表达式,而不仅仅是标识符),则f + (float) i在编译器的分析中应等效,并且获得相同的优化。

One way to understand why this is is that, in parsing f + i , the compiler will recognize that i must be converted to float , and it will construct, in its internal representation of the program, statements to get f , get i , convert i to float , and add them. 理解其原因的一种方法是,在解析f + i ,编译器将认识到必须将i转换为float ,并且它将在程序的内部表示中构造语句get f ,get i ,convert i float ,并添加它们。 When analyzing f + (float) i , the same internal representation will be constructed, so the two statements will be equivalent. 分析f + (float) i ,将构造相同的内部表示形式,因此这两个语句将等效。

That said, I expect cases where the compiler can optimize may be fairly limited. 就是说,我希望编译器可以优化的情况相当有限。 Compilers may recognize specific situations such as adding two constants, adding a float zero to an integer, and adding an integer zero to a float . 编译器可能会识别某些特定情况,例如添加两个常量,将float零添加到整数,以及将整数零点添加到float Sometimes the compiler might be able to deduce values for f and i even if they are expressions or identifiers, rather than constants, because the flow of prior code necessarily produces some value, and then it might be able to optimize based on the deduced values. 有时,编译器可能能够推论fi值,即使它们是表达式或标识符而不是常量,因为先前代码的流程必然会产生一些值,然后它可能能够根据推导的值进行优化。

So, special cases may be recognized. 因此,可以识别特殊情况。 I would not expect the compiler to be able to generally turn f + i into any sort of optimized bit-twiddling that would be faster than a floating-point add (or whatever instruction the compiler would normally use). 我不希望编译器通常能够将f + i转换为比浮点加法(或编译器通常使用的任何指令)更快的任何优化的位扭曲。 However, in theory, it could happen, and, if so, a well-designed compiler ought to optimize f + i the same as f + (float) i . 但是,从理论上讲,这是有可能发生的,并且如果是这样,一个设计良好的编译器应该将f + if + (float) i相同地进行优化。 (Perhaps there are C implementations with floating-point support in software instead of hardware that might handle an add of a floating-point value and an integer in a faster way than an add of two floating-piont values.) (也许有一些在软件中而不是在硬件中支持浮点的C实现,它们可能比以两个浮点值的添加更快的方式处理浮点值和整数。)

I was curious too so I've done some quick tests and I've observed the following behaviors: 我也很好奇,所以我做了一些快速测试,并观察到以下行为:

The execution time of this fragment of code was: 该代码片段的执行时间为:

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

And with a float promotion: 并通过浮动促销:

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

This is just one circumstance. 这只是一种情况。 Surely this is not the best way to check and i'm sure the compiler could do it better or worse depending on the situation but I observed a little difference in time with optimitzation O2. 当然,这不是检查的最佳方法,并且我确信编译器可以根据情况进行更好或更坏的选择,但是我发现优化O2的时间有所不同。

**Runs were made in c++11. **运行是在c ++ 11中进行的。 CPU architecture: AMD64** CPU架构:AMD64 **

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM