1

Consider the following

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

if x is always less than 5, does visual studio compiler do any optimization? i.e. like never checks if x is larger than 5 and always run function B

Emo
  • 546
  • 4
  • 7
  • 22
  • it's the compiler that does optimizations, not visual studio. – george.zakaryan Oct 08 '12 at 08:43
  • I meant to say VS compiler; does it really do so ? is there a way to confirm that ? – Emo Oct 08 '12 at 08:47
  • 1
    Yes - check the disassembly. Also optimizing this will depend on the type of variable `x` is: a const will probably result in the check getting optimized away, but if `x` is a complex type overriding `operator>` it probably won't. And remember optimizations depend on compiler flags, which for debug are turned off, so you get either no or minimum optimizations. – mtsvetkov Oct 08 '12 at 08:50
  • how can I check the disassembly ? – Emo Oct 08 '12 at 09:04
  • Additionally the CPU does [branch prediction](http://en.wikipedia.org/wiki/Branch_predictor) too. It is able to "remember" which part of the if-statement has been executed more often. It will then optimize the code execution accordingly. – s3rius Oct 08 '12 at 13:40

1 Answers1

4

It depends on whether or not the compiler "knows" that x will always be less than 5.

Yes, nearly all modern compilers are capable of removing the branch. But the compiler needs to be able to prove that the branch will always go one direction.


Here's an example that can be optimized:

int x = 1;

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

The disassembly is:

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

x = 1 is provably less than 5. So the compiler is able to remove the branch.


But in this example, even if you always input less than 5, the compiler doesn't know that. It must assume any input.

int x;
cin >> x;

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

The disassembly is:

    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

The branch stays. But note that it actually hoisted the function call out of the branch. So it really optimized the code down to something like this:

const char *str = "Hello\n";

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

printf(str);
Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • Thanks ... what if i am reading a value from the gui or command line, is there a way to prove to the compiler that the value read from the gui or command line will never change till the process is over ? – Emo Oct 08 '12 at 09:42
  • 1
    I misread your comment. So here's an update: Unfortunately, no you won't be able to avoid the branch without code-duplication. But in any case, the branch will consistently go the same way so it's almost free due to [branch-prediction](http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array/11227902#11227902). – Mysticial Oct 08 '12 at 09:56