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

C++ C++;:编译器是否优化整数+;浮点算术运算?,c++,optimization,compilation,floating-point,integer,C++,Optimization,Compilation,Floating Point,Integer,当一方是整数类型,而另一方是浮点类型时,编译器是否能够优化算术运算?或者,在100%的情况下,在执行操作之前,整数会被提升为浮点吗 我问这个问题的原因是,为了清楚起见,我喜欢自己执行浮点提升,但如果它保留了编译器可以利用的情况,我可能会停止这样做。在编译器可以优化浮点和整数之间的加法的情况下,例如,将3.f+1优化为4而不是在运行时执行加法,我希望强制转换的存在对编译器是否能够优化没有影响 这是一个一般性的陈述,基于现代编译器的工作方式,而不是逻辑上的必然性。在编译器识别出一些f+i可以优化的情

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


我问这个问题的原因是,为了清楚起见,我喜欢自己执行浮点提升,但如果它保留了编译器可以利用的情况,我可能会停止这样做。

在编译器可以优化浮点和整数之间的加法的情况下,例如,将
3.f+1
优化为
4
而不是在运行时执行加法,我希望强制转换的存在对编译器是否能够优化没有影响

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

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

也就是说,我认为编译器可以优化的情况可能相当有限。编译器可以识别特定情况,例如添加两个常量、将
浮点
零添加到整数,以及将整数零添加到
浮点
。有时,编译器可能能够推导出
f
i
的值,即使它们是表达式或标识符,而不是常量,因为先前的代码流必然会产生一些值,然后它可能能够基于推导出的值进行优化


因此,特殊情况可能会得到承认。我不希望编译器一般能够将
f+I
转换为比浮点加法(或编译器通常使用的任何指令)更快的任何类型的优化位旋转。然而,从理论上讲,这是可能发生的,如果是这样,一个设计良好的编译器应该优化
f+i
,就像优化
f+(float)i
一样。(可能有一些在软件而不是硬件中支持浮点的C实现,它们处理浮点值和整数的加法比处理两个浮点值的加法更快。)

在编译器可以优化浮点值和整数之间的加法的情况下,例如,将
3.f+1
优化为
4
而不是在运行时执行加法,我希望强制转换的存在对编译器是否能够优化没有影响

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

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

也就是说,我认为编译器可以优化的情况可能相当有限。编译器可以识别特定情况,例如添加两个常量、将
浮点
零添加到整数,以及将整数零添加到
浮点
。有时,编译器可能能够推导出
f
i
的值,即使它们是表达式或标识符,而不是常量,因为先前的代码流必然会产生一些值,然后它可能能够基于推导出的值进行优化


因此,特殊情况可能会得到承认。我不希望编译器一般能够将
f+I
转换为比浮点加法(或编译器通常使用的任何指令)更快的任何类型的优化位旋转。然而,从理论上讲,这是可能发生的,如果是这样,一个设计良好的编译器应该优化
f+i
,就像优化
f+(float)i
一样。(也许有些C实现在软件而不是硬件中支持浮点,它们处理浮点值和整数的加法比处理两个浮点值的加法更快。)

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

此代码片段的执行时间为:

for (int i = 0; i < 1000000000; ++i) {
    f = f + 1;
}
for(int i=0;i<100000000;++i){
f=f+1;
}
  • 无-O2标志:2156.25ms
  • 带-O2标志:953.125ms
并通过浮动促销:

for (int i = 0; i < 1000000000; ++i) {
    f = f + (float)1;
}
for(int i=0;i<100000000;++i){
f=f+(浮动)1;
}
  • 无-O2标志:2156.25ms
  • 带-O2标志:968.75ms
这只是一种情况。苏