【问题标题】:Does compiler optimize away intermediaries [closed]编译器是否优化了中介[关闭]
【发布时间】:2014-05-23 10:26:09
【问题描述】:

我正在尝试优化以下代码的夸张版本。

int a = startvalue1;
int b = startvalue2;
int c = startvalue3;

int ta = a + b;
int tb = b + c;
int tc = c + a;

int tta = ta * tb;
int ttb = tb * tc;
int ttc = tc * ta;

int finalvalue1 = tta - ttc;
int finalvalue2 = ttb - ttc;
int finalvalue3 = ttc + tta;

编译器会自动摆脱中介吗?如果没有,如果我摆脱它们,我的代码会运行得更快吗?

我已经分析了我的程序,我必须优化我的离散傅立叶变换。但是摆脱中介会很乏味,如果编译器要为我做这件事,我想避免它。

【问题讨论】:

  • 当然。你唯一能做错的就是不自己检查这个,看看反汇编。
  • 通常查看优化器对您的代码所做的事情的方法是查看生成的程序集。
  • 问题是没有明确的是或否答案。这取决于编译器、编译器选项、周围的代码等……唯一确定的方法是查看程序集。
  • 如果您想确定在您的环境中编译的代码以特定方式优化,那么您需要进行这项研究。一般的答案可能正确,也可能不正确,尤其是因为您只展示了一段代码,而不是全部。

标签: c++ optimization compiler-construction


【解决方案1】:

在使用优化进行编译时,您需要查看编译器的反汇编输出。

如果您使用 Visual Studio,请设置断点并按 ctrl+f11。
如果使用 gcc,请使用 -S 标志输出程序集。

在我的系统上,Visual Studio 2012 删除了所有中间步骤。

这是我写的测试程序:

#include <iostream>

int main (void)
{
    int startvalue1 = 10 ;
    int startvalue2 = 15 ;
    int startvalue3 = 20 ;

    int a = startvalue1;
    int b = startvalue2;
    int c = startvalue3;

    int ta = a + b;
    int tb = b + c;
    int tc = c + a;

    int tta = ta * tb;
    int ttb = tb * tc;
    int ttc = tc * ta;

    int finalvalue1 = tta - ttc;
    int finalvalue2 = ttb - ttc;
    int finalvalue3 = ttc + tta;

    // This line is only here make sure everything isn't optimized out!
    std::cout << finalvalue1 << finalvalue2 << finalvalue3 ;

    return 0 ;
}

这是优化后的程序集:

01291270 8B 0D 30 30 29 01    mov         ecx,dword ptr ds:[1293030h]  
01291276 68 59 06 00 00       push        659h  
0129127B 68 2C 01 00 00       push        12Ch  
01291280 6A 7D                push        7Dh  
01291282 FF 15 38 30 29 01    call        dword ptr ds:[1293038h]  
01291288 8B C8                mov         ecx,eax  
0129128A FF 15 38 30 29 01    call        dword ptr ds:[1293038h]  
01291290 8B C8                mov         ecx,eax  
01291292 FF 15 38 30 29 01    call        dword ptr ds:[1293038h]
01291298 33 C0                xor         eax,eax  
0129129A C3                   ret

这大致相当于:

#include <iostream>

int main (void)
{
    std::cout << 125 << 300 << 1625 ;
    return 0 ;
}

【讨论】:

  • 非常感谢。哇,它优化了一切。感谢组装提示。
  • @deanresin 许多人低估了编译器优化的力量。请记住,编译器通常是由非常聪明的人编写的。
  • 如果您不使用常量作为值,代码可能看起来不同。
  • @RetiredNinja 说得好。我将检查使用外部函数的反汇编作为 OP 的练习。
  • @jliv902 事实证明,考虑到常量大声笑,您的答案毫无用处。谢谢你的尝试。我查看了程序集,可以看到其中的中间变量名称,所以我认为这意味着至少有一些中间变量没有被编译掉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-24
  • 2011-03-18
  • 1970-01-01
  • 2010-09-21
  • 2010-11-22
  • 2014-04-18
  • 2011-05-16
相关资源
最近更新 更多