Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some example of __assume leading to a faster code other than "no default" in switch?

Documentation for __assume says "The most common use of __assume is with the default case of a switch statement, as shown in the following example.".

  • Is there any other case where __assume can lead to a more efficient (or even a different) code?
  • When inside of if / else , is compiler automatically "assuming" what is already know because of if condition?

I was unable to find any non-trivial example which would show any of above - I hope someone else could.

like image 893
Suma Avatar asked Jun 22 '10 20:06

Suma


1 Answers

Consider the following code, compiled with the /Ox switch:

if (1) {
  printf("live code\n");
} else {
  printf("dead code\n");
}

The optimizer will optimize away the else. Now consider:

int x = 1;
if (x == 1) {
  printf("live code\n");
} else {
  printf("dead code\n");
}

The optimizer will once again optimize away the else. Also consider:

int x = 1;
__assume(x != 1);
if (x == 1) {
  printf("live code\n");
} else {
  printf("dead code\n");
}

The optimizer will optimize away the if this time -- incorrectly so.

To test, build a test program in Release mode (with the /Ox and /Zi options) and look at the generated assembly (Alt+8 in Visual Studio.)

Now consider the above if/else condition being tested in an inline method. In certain contexts, the programmer may know that the inline method is called with a particular value and the optimizer may not have realized this fact. Using __assume at the caller level in the manner illustrated above, just before the inlined method is called, can theoretically help the optimizer.

From Optimization Best Practices (quote from older version):

__assume has been in Visual C++ for multiple releases, but it has become much more usable in Visual C++ 2005. With __assume, a developer can tell the compiler to make assumptions about the value of some variable.

For example __assume(a < 5); tells the optimizer that at that line of code the variable a is less than 5. Again this is a promise to the compiler. If a is actually 6 at this point in the program then the behavior of the program after the compiler has optimized may not be what you would expect. __assume is most useful prior to switch statements and/or conditional expressions.

There are some limitations to __assume. First, like __restrict, it is only a suggestion, so the compiler is free to ignore it. Also, __assume currently works only with variable inequalities against constants. It does not propagate symbolic inequalities, for example, assume(a < b).

like image 90
vladr Avatar answered Oct 31 '22 17:10

vladr