【问题标题】:Visual Studio performance optimization in branching分支中的 Visual Studio 性能优化
【发布时间】:2012-10-08 08:40:04
【问题描述】:

考虑以下

while(true)
{
    if(x>5)
     // Run function A
    else
     // Run function B
}

如果 x 总是小于 5,Visual Studio 编译器会做任何优化吗?即 like 从不检查 x 是否大于 5 并始终运行函数 B

【问题讨论】:

  • 进行优化的是编译器,而不是 Visual Studio。
  • 我是说VS编译器;真的是这样吗?有没有办法确认?
  • 是的 - 检查反汇编。同样优化这将取决于变量x 的类型是: const 可能会导致检查被优化,但如果x 是覆盖operator> 的复杂类型,它可能不会。请记住,优化依赖于编译器标志,对于调试,这些标志是关闭的,所以你要么没有优化,要么得到最低限度的优化。
  • 如何检查反汇编?
  • 此外,CPU 也执行branch prediction。它能够“记住” if 语句的哪一部分执行得更频繁。然后它将相应地优化代码执行。

标签: visual-studio-2010 performance c#-4.0 optimization compiler-optimization


【解决方案1】:

这取决于编译器是否“知道”x 总是小于5

是的,几乎所有现代编译器都能够删除分支。但是编译器需要能够证明该分支将始终朝着一个方向发展。


这是一个可以优化的例子:

int x = 1;

if (x > 5)
    printf("Hello\n");
else
    printf("World\n");

反汇编是:

    sub rsp, 40                 ; 00000028H
    lea rcx, OFFSET FLAT:??_C@_06DKJADKFF@World?6?$AA@
    call    QWORD PTR __imp_printf

x = 1 可证明小于5。所以编译器能够删除分支。


但是在这个例子中,即使你总是输入小于 5,编译器也不知道。它必须承担任何输入。

int x;
cin >> x;

if (x > 5)
    printf("Hello\n");
else
    printf("World\n");

反汇编是:

    cmp DWORD PTR x$[rsp], 5
    lea rcx, OFFSET FLAT:??_C@_06NJBIDDBG@Hello?6?$AA@
    jg  SHORT $LN5@main
    lea rcx, OFFSET FLAT:??_C@_06DKJADKFF@World?6?$AA@
$LN5@main:
    call    QWORD PTR __imp_printf

分支保留。但请注意,它实际上将函数调用提升到了分支之外。所以它真的把代码优化成这样:

const char *str = "Hello\n";

if (!(x > 5))
    str = "World\n";

printf(str);

【讨论】:

  • 谢谢...如果我从 gui 或命令行读取值怎么办,有没有办法向编译器证明从 gui 或命令行读取的值永远不会改变,直到进程结束了?
  • 我误读了您的评论。所以这里有一个更新:不幸的是,没有代码重复,你将无法避免分支。但无论如何,由于branch-prediction,分支将始终以相同的方式运行,因此它几乎是免费的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
  • 2012-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多