2009-08-13 2 views
6

Встроенные функции - это всего лишь запрос компиляторам, которые вставляют полный кусок встроенной функции в каждое место в коде, где используется эта функция.Встроенная функция (когда вводить)?

Но как компилятор решает, следует ли его вставлять или нет? Какой алгоритм/механизм он использует для принятия решения?

Спасибо,

Нэвин

+1

Это не просьба - это рекомендация. Решение зависит от компилятора – chester89

ответ

4

Некоторые общие аспекты:

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

3-я, вероятно, суть вашего вопроса, но это на самом деле «специфические эвристики для компилятора» - вам нужно проверить документы компилятора, но обычно они не будут давать много гарантий. MSDN имеет некоторую (ограниченную) информацию для MSVC.

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

большие возможности для встраивание является удаление пути кода, который знает, что компилятор не будет принято - как крайний пример:

inline int Foo(bool refresh = false) 
{ 
    if (refresh) 
    { 
     // ...extensive code to update m_foo 
    } 
    return m_foo; 
} 

Хороший компилятор будет встраивать Foo(false), но не Foo(true).

С Link Время генерации кода, Foo может находиться в .cpp (без inline declararion), и Foo(false) все равно будет встраиваемыми, так что опять рядный имеет лишь незначительное воздействие здесь.


Резюмируя: Есть несколько сценариев, в которых вы должны попытаться принять ручное управление встраивание путем размещения (или опуская) встроенные заявления.

-2

он вставляет, если вы пишете "встроенный" в начале функции?

+2

Не нужно. Это просто просьба. – Naveen

+0

Для C++ это в основном означает, что он не вызывает ссылок-ошибок, если разные объектные файлы содержат одно и то же определение. Это требуется стандартом.Использование 'inline' или нет обычно не коррелирует каким-либо образом, действительно ли функция встраивается. – gimpf

+0

хотя бы комментарии сообщают людям :) – ufukgun

2

Все, что я знаю о встроенных функциях (и многих других материалах на C++), это here.

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

1

Я уверен, что большинство компиляторов принимают решение в зависимости от длины функции (при компиляции) в байтах и ​​как часто она используется по сравнению с типом оптимизации (скорость и размер).

1

Я знаю только критерии пары:

  • Если рядные соответствует рекурсии - рядный будет игнорироваться.
  • выключатель/во время/как в большинстве случаев вызывает компилятор игнорировать рядный
1

Это зависит от компилятора. Вот (первая часть), что руководство GCC говорит:

 
    -finline-limit=n 
      By default, GCC limits the size of functions that can be inlined. 
      This flag allows the control of this limit for functions that are 
      explicitly marked as inline (i.e., marked with the inline keyword 
      or defined within the class definition in c++). n is the size of 
      functions that can be inlined in number of pseudo instructions (not 
      counting parameter handling). The default value of n is 600. 
      Increasing this value can result in more inlined code at the cost 
      of compilation time and memory consumption. Decreasing usually 
      makes the compilation faster and less code will be inlined (which 
      presumably means slower programs). This option is particularly 
      useful for programs that use inlining heavily such as those based 
      on recursive templates with C++. 

      Inlining is actually controlled by a number of parameters, which 
      may be specified individually by using --param name=value. The 
      -finline-limit=n option sets some of these parameters as follows: 

      @item max-inline-insns-single 
      is set to I/2. 
      @item max-inline-insns-auto 
      is set to I/2. 
      @item min-inline-insns 
      is set to 130 or I/4, whichever is smaller. 
      @item max-inline-insns-rtl 
      is set to I. 

      See below for a documentation of the individual parameters 
      controlling inlining. 

      Note: pseudo instruction represents, in this particular context, an 
      abstract measurement of function's size. In no way, it represents 
      a count of assembly instructions and as such its exact meaning 
      might change from one release to an another. 
2

Ниже в FAQ для Sun Studio 11 компилятора:

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

  • Вы компилируете с + d.
  • Вы компилируете с -g.
  • Адрес функции необходим (как с виртуальной функцией).
  • Функция содержит структуры управления, которые компилятор не может сгенерировать.
  • Функция слишком сложна.

В соответствии с этим ответ на post путем «» clamage45 «пусковыми структур, которые компилятор не может генерировать инлайн» являются:

  • функция содержит запрещенные конструкции, как петли , коммутатор или Гото

Другой список можно найти here. Как уточнили большинство других ответов эвристика будет 100% компилятора конкретных, от того, что я прочитал, я думаю, чтобы убедиться, что функция на самом деле встраиваемые вам нужно избегать:

  • локальных статической переменных
  • петля конструкции
  • переключатель заявления
  • попробовать/поймать
  • Гото
  • рекурсии
  • и, конечно, слишком сложной (независимо от того, что т eans)
Смежные вопросы