发布模式跳过部分代码

Sii*_*las 4 c++ compiler-optimization

在尝试测试函数的速度时,我发现并非我的代码的所有部分都在Release模式下工作.但是,相同的代码在Debug模式下完美运行.

我正在使用VC++编译器进行/O2优化.

这是切出的部分,不起作用.

int main()
{
    boost::timer::auto_cpu_timer t;

    for(int i = 0; i < 1000000; i++)
        gcdb(i, 5);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在释放模式下生成的程序集,for循环的代码仅在此模式下丢失.

int main()
{
000000013F8E1280  sub         rsp,88h  
000000013F8E1287  mov         rax,qword ptr [__security_cookie (013F8E7150h)]  
000000013F8E128E  xor         rax,rsp  
000000013F8E1291  mov         qword ptr [rsp+70h],rax  
    boost::timer::auto_cpu_timer t;
000000013F8E1296  lea         rcx,[t]  
000000013F8E129B  mov         edx,6  
000000013F8E12A0  call        boost::timer::auto_cpu_timer::auto_cpu_timer (013F8E2DA0h)  

    for(int i = 0; i < 1000000; i++)
        gcdb(i, 5);
    return 0;
000000013F8E12A5  lea         rcx,[t]  
000000013F8E12AA  call        boost::timer::auto_cpu_timer::~auto_cpu_timer (013F8E2810h)  
000000013F8E12AF  xor         eax,eax  
}
Run Code Online (Sandbox Code Playgroud)

gcdb() 只是找到两个数字的GCD的函数.

什么可能导致此代码跳过?

Mys*_*ial 8

您在这里看到的是称为死代码消除的编译器优化.

当编译器发现不需要某些代码的结果时,可以自由地消除它.这是所有现代编译器采用的标准优化.

保持编译器不优化它的解决方法是以某种方式实际使用输出:

int main()
{
    boost::timer::auto_cpu_timer t;

    int sum = 0;

    for(int i = 0; i < 1000000; i++)
        sum += gcdb(i, 5);

    cout << sum << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

相关:GCC如何优化循环内递增的未使用变量?

  • @Ynau:编译器检测到`gcdb`没有副作用,因此可以删除它而不改变程序的功能; 类似地,可以删除`for`循环.这就是优化的目的:在不改变功能的情况下提高性能. (2认同)