释放模式跳过部分代码

Release mode skipping parts of code

本文关键字:代码 过部 模式 释放      更新时间:2023-10-16

在尝试测试函数的速度时,我发现并非所有代码部分都在Release模式下工作。不过,相同的代码在Debug模式下可以完美地工作。

我使用的是带有/O2优化的VC++编译器。

这是切除的部分,不起作用。

int main()
{
    boost::timer::auto_cpu_timer t;
    for(int i = 0; i < 1000000; i++)
        gcdb(i, 5);
    return 0;
}

在发布模式下生成的程序集,只有在该模式下才缺少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  
}

CCD_ 4只是求两个数的GCD的函数。

是什么原因导致此代码跳过?

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

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

防止编译器优化它的一个方法是以某种方式实际使用输出:

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;
}

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

如果编译器能够证明没有副作用,并且您没有在任何地方使用结果,那么可以完全修剪该循环。

尝试对结果求和,然后从main返回整数和——这样会有一个可观察到的副作用,应该会阻止优化器变得过于聪明。