2012-01-27 77 views
4

当试图测试函数的速度时,我发现我的代码并非全部工作在Release模式。不过,相同的代码在Debug模式下完美工作。发布模式跳过代码部分

我正在使用VC++编译器与/O2优化。

下面是切出的部分,它不起作用。

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 
} 

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

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

+2

编译器优化它,不是一个好理由吗? – 2012-01-27 17:16:47

+0

我是否可以避免优化那部分? – SMK 2012-01-27 17:19:20

+1

尝试在循环外声明一个变量并为其分配'gcdb()'的结果。 – lapk 2012-01-27 17:22:00

回答

8

你在这里看到的是一种称为Dead Code Elimination的编译器优化。

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

一个变通,以使编译器优化它是实际使用的输出以某种方式:

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

相关:How does GCC optimize out an unused variable incremented inside a loop?

+0

谢谢,这样做! – SMK 2012-01-27 17:22:52

+2

@Ynau:编译器检测到'gcdb'没有副作用,因此可以在不改变程序功能的情况下将其删除;同样,'for'循环可以被删除。这是优化的目的:在不改变功能的情况下提高性能。 – MRAB 2012-01-27 17:25:51

+0

您是否也可以在调试模式下运行,但是在不调试的情况下执行调试? – 2013-01-22 04:15:18

2

如果编译器可以证明有没有副作用效果,并且您不会在任何地方使用结果,因此可以完全修剪该循环。

尝试总结结果,然后从main中返回整数和 - 这样就存在一个可观察的副作用,应该停止优化器过于聪明。