Рассмотрим следующий код, скомпилированный с помощью переключателя /Ox
:
if (1) {
printf("live code\n");
} else {
printf("dead code\n");
}
Оптимизатор оптимизирует else
.Теперь рассмотрим:
int x = 1;
if (x == 1) {
printf("live code\n");
} else {
printf("dead code\n");
}
Оптимизатор снова оптимизирует else
.Также учтите:
int x = 1;
__assume(x != 1);
if (x == 1) {
printf("live code\n");
} else {
printf("dead code\n");
}
Оптимизатор будет оптимизировать if
на этот раз - неправильно, так что.
Для тестирования создайте тестовую программу в режиме Release (с /Ox
и /Zi
опций) и посмотрите на сгенерированную сборку (Alt+8
в Visual Studio.)
Теперь рассмотрим вышеупомянутое условие if/else
, тестируемое ввстроенный метод.В определенных контекстах программист может знать, что встроенный метод вызывается с определенным значением, и оптимизатор может не осознавать этот факт.Использование __assume
на уровне вызывающей стороны, как показано выше, непосредственно перед вызовом встроенного метода, может теоретически помочь оптимизатору.
С Рекомендации по оптимизации :
__ предположим, что он был в Visual C ++ для нескольких выпусков, но в Visual C ++ 2005 он стал гораздо более удобным для использования. С __assume разработчик может сказать компилятору делать предположения о значении некоторой переменной.
Например __assume (a <5);сообщает оптимизатору, что в этой строке кода переменная a меньше 5. Опять же, это обещание компилятору.Если в этот момент в программе значение a равно 6, то поведение программы после оптимизации компилятора может не соответствовать ожидаемому.__assume наиболее полезен до операторов switch и / или условных выражений. </p>
Существуют некоторые ограничения для __assume.Во-первых, как и __restrict, это всего лишь предложение, поэтому компилятор может его игнорировать.Кроме того, __assume в настоящее время работает только с переменными неравенствами против констант.Он не распространяет символические неравенства, например, предполагает (a