Оптимизирует ли компилятор локальные переменные встроенной функции - PullRequest
0 голосов
/ 16 марта 2012

Теперь я прочитал четвертый раздел книги Inside The C++ Object Model и у меня возник вопрос.

Встроенная функция, подобная этой:

inline int max(int a, int b)
{
    return (a > b) ? a : b;
}

Затем такое утверждение, как следующее: a = max(x, y);

это утверждение будет преобразовано в a = (x > y) ? x : y;

Но в книге говорится, когда добавляются локальные переменные к встроенной функции, например:

inline int max(int a, int b)
{
    int maxval = (a > b) ? a : b;
    return maxval;
}

Будет преобразовано в

int __max_lv_maxval;
a = (__max_lv_maxval = (x > y) ? x : y), __max_lv_maxval;

И очевидно, что производительность функции снизится.

У меня вопрос: оптимизирует ли компиляция (например, VC2010, gcc) встроенную функцию и удаляет локальные переменные?

Ответы [ 4 ]

6 голосов
/ 16 марта 2012

Кажется, что в этой книге предполагается, что компилятор встроен на уровне исходного кода, это, конечно, полностью зависит от компилятора.Большинство из них начнут встраивание на уровне AST, где могут и будут происходить преобразования и определенные оптимизации.Все это предполагает, что компилятор будет встроить код.

Если мы посмотрим на вашу функцию, любой приличный компилятор превратит их обоих в один и тот же код IR, так как онскомпилирует встроенную функцию до того, как она будет встроена, таким образом, временная функция требуется независимо (на уровне IR).когда IR тогда фактически встроен, временное будет свернуто и вместо этого заменено назначением назначения вызова на max.

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

Итог: Это полностью зависит от вашего компилятора, уровней оптимизации и того, как он выполняет анализ переменных живучести, распространения значений и свертывания.

1 голос
/ 16 марта 2012

Любые интересные преобразования, которые мы можем сделать с кодом, компилятор может сделать также. А потом некоторые!

Когда компилятор видит, что

inline int max(int a, int b) 
{
     return (a > b) ? a : b; 
} 

a = max(x, y);

можно преобразовать в

 a = (x > y) ? x : y;

Также легко увидеть, что сохранение значения в переменной, которая никогда не используется позже, не имеет смысла. Хранилище (и переменную) можно удалить без изменения результата программы.

Локальные переменные в небольших функциях часто хранятся в регистрах ЦП и вообще никогда не сохраняются в памяти.

1 голос
/ 16 марта 2012
inline int max(int a, int b)
{
    return (a > b) ? a : b;
}

Затем, например, следующее: a = max(x, y);

это утверждение будет преобразовано в a = (x > y) ? x : y;

Это не так просто. inline это подсказка, а не требование. Ключевое слово немного меняет правила, но не заставляет вставлять. Вы также забываете, что a и b являются также локальными переменными для функции max, и та же книга, в которой предполагается, что локальные переменные не могут быть оптимизированы, предполагает, что эти локальные переменные можно оптимизировать вне , Они могут быть оптимизированы в тех случаях, когда это безопасно, а могут и не быть, в зависимости от параметров компилятора и компилятора. Для работы в отладчике может иметь смысл сохранить их. Они могут не оптимизироваться, когда это небезопасно, например, когда x и y равны volatile. В этом случае (x > y) ? x : y читает один из них дважды, что является потенциально видимым и, следовательно, недействительным, изменением поведения.

0 голосов
/ 16 марта 2012

Компилятор просто делает, как у вас есть шоу. если мы называем это встроенное веселье, как это

void example()
{
  int m = max(10, 11);
}

расширение будет

{
  int __max_lv_maxval;// mangled inline local variable  
 int m = (__max_lv_maxval = (x > y) ? x : y), __max_lv_maxval;
}

Как правило, каждая локальная переменная внутри встроенной функции должна быть введена во включающий блок вызова в качестве переменной с уникальным именем. GCC больше не сделает для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...