Решает ли компилятор, когда встроить мои функции (на C ++)?

StackOverflow https://stackoverflow.com/questions/1204975

Вопрос

Я понимаю, что вы можете использовать ключевое слово inline или просто поместить метод в объявление класса, например, короткий ctor или метод getter, но принимает ли компилятор окончательное решение о том, когда внедрять мои методы?

Например:

inline void Foo::vLongBar()
{
   //several function calls and lines of code
}

Будет ли компилятор игнорировать мое встроенное объявление, если он считает, что это сделает мой код неэффективным?

В качестве побочной проблемы, если у меня есть метод getter, объявленный вне моего класса следующим образом:

void Foo::bar() { std::cout << "baz"; }

Будет ли компилятор встроить это под прикрытием?

Это было полезно?

Решение

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

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

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

Другие советы

Да, окончательное решение о том, встроить ваш код или нет, лежит на компиляторе C ++.Ключевое слово inline - это предложение, а не требование.

Вот некоторые подробности о том, как это решение обрабатывается в компиляторе Microsoft C ++

Как уже писали многие, окончательное решение всегда остается за компилятором, даже если вы можете дать твердые подсказки, такие как forceinline.
Часть обоснования заключается в том, что встраивание не является автоматическим "идти быстрее" переключатель. Слишком большое встраивание может сделать ваш код намного больше и может помешать другим оптимизациям. См. справку C ++ FAQ по встроенным функциям и производительности .

Как уже отмечали другие, ключевое слово inline является всего лишь предложением компилятору встроить код. Поскольку компилятор будет обычно встроенный код, который не был помечен inline , а не встроенным кодом, который имеет, ключевое слово выглядит таким же избыточным, как register или (pre-C ++ 0x) auto .

Однако есть еще одна вещь, на которую влияет ключевое слово inline : он изменяет связь функции с external (по умолчанию для функции) в встроенный . Встроенное связывание позволяет каждому модулю компиляции содержать собственную копию объектного кода, а компоновщик удаляет избыточные копии из конечного исполняемого файла. Если это напоминает вам шаблоны, да, шаблоны также используют встроенную связь.

Просто чтобы добавить свои 5 центов ...

Я нашел это Гуру недели статья о встраивании очень полезная.

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

С уважением,
Ованес

  

В качестве дополнительной проблемы, если у меня есть метод получения, объявленный вне моего класса, например:

void Foo::bar() { std::cout << "baz"; }
  

Будет ли компилятор встроен в это под покровом?

Это зависит. Это может быть сделано для всех вызывающих абонентов в одном модуле перевода (файл .cpp и все его #included определения). Но он все еще должен скомпилировать не встроенную версию, потому что могут быть вызывающие функции этой функции за пределами модуля перевода. Вы можете увидеть это на работе (если ваш компилятор действительно может это сделать) на высоких уровнях оптимизации. (В частности: сравните то, что происходит, когда вы #include все ваши файлы .cpp в одном .cpp с типичным макетом. Со всеми определениями в одном модуле перевода возможности для такого встраивания резко возрастают.)

Насколько я знаю, компилятор автоматически сделает функцию, которую вы объявили встроенной (или написанной в объявлении класса), не-встроенную, если он найдет цикл, например for, while и т. д. Это один из примеров, когда компилятор имеет последнее слово во встроенных функциях.

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

Вот почему ключевое слово «inline» (и даже в некоторых случаях принудительные варианты) может позволить себе не иметь стандартного способа его принудительного применения - вы всегда можете просто написать макрос.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top