Некоторые примеры __assume, приводящие к более быстрому коду, отличному от «no default» в switch? - PullRequest
8 голосов
/ 23 июня 2010

Документация для __assume гласит: «Наиболее распространенное использование __assume - это регистр оператора по умолчанию, как показано в следующем примере.».

  • Есть ли другой случай, когда __assume может привести к более эффективному (или даже другому) коду?
  • Когда внутри if / else автоматически компилятор "предполагает", что уже известно из условия if?

Мне не удалось найти ни одного нетривиального примера, который мог бы показать что-либо из вышеперечисленного - я надеюсь, что кто-то еще мог.

1 Ответ

8 голосов
/ 09 августа 2010

Рассмотрим следующий код, скомпилированный с помощью переключателя /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

...