Каковы преимущества / недостатки использования встроенных функций в C ++? Я вижу, что это только увеличивает производительность для кода, который выводит компилятор, но с современными оптимизированными компиляторами, быстрыми процессорами, огромной памятью и т. Д. (Не так, как в 1980 году <где памяти было мало, и все должно было уместиться в 100 КБ памяти), что преимущества они действительно имеют сегодня?
c++
inline-functions
Lennie De Villiers
источник
источник
inline
это ключевое слово c ++, а встраивание - это метод оптимизации компилятора. Посмотрите этот вопрос « когда я должен написать ключевое словоinline
для функции / метода » для правильного ответа.Ответы:
Встроенные функции работают быстрее, потому что вам не нужно вставлять и извлекать такие вещи из стека, как параметры и адрес возврата; однако, это делает ваш двоичный файл немного больше.
Имеет ли это существенное значение? Не заметно на современном оборудовании для большинства. Но это может иметь значение, которого достаточно для некоторых людей.
Маркировка чего-то встроенного не дает вам гарантии, что это будет встроено. Это просто предложение для компилятора. Иногда это невозможно, например, когда у вас есть виртуальная функция или когда задействована рекурсия. И иногда компилятор просто решает не использовать его.
Я мог видеть ситуацию, подобную этой, имеющую заметную разницу:
источник
преимущества
Недостатки
Магия
return 42 ;
утверждению. Это для меня экстремальное встраивание . Это случается редко в реальной жизни, это увеличивает время компиляции, не увеличивает ваш код и делает ваш код быстрее. Но, как и Грааль, не пытайтесь применять его везде, потому что большая часть обработки не может быть решена таким образом ... Тем не менее, это круто в любом случае ...:-p
источник
3.2/6: There can be more than one definition of [..] inline function with external linkage [..] non-static function template
. На 5.1.5 / 6For a generic lambda, the closure type has a public inline function call operator member template
. И7.1.2/2: the use of inline keyword is to declare an inline function
там, где есть предложение встроить тело функции в точке вызова. Итак, я прихожу к выводу, что даже если они могут вести себя одинаково, встроенные функции и шаблоны функций по-прежнему являются отдельными, ортогональные понятия, которые можно смешивать (т.В архаичных C и C ++
inline
это похоже наregister
: предложение (не более, чем предложение) компилятору о возможной оптимизации.В современном C ++
inline
сообщает компоновщику, что, если несколько определений (не объявлений) находятся в разных единицах перевода, они все одинаковы, и компоновщик может свободно хранить одно и отбрасывать все остальные.inline
является обязательным, если функция (независимо от того, насколько сложная или «линейная») определена в заголовочном файле, чтобы позволить нескольким источникам включать ее без получения компоновщиком ошибки «множественного определения».Функции-члены, определенные внутри класса, по умолчанию являются «встроенными», как и шаблонные функции (в отличие от глобальных функций).
Обратите внимание на включение файла file..h в два файла .cpp, в результате чего получается два экземпляра
afunc()
. Линкер откажется от одного из них. Если нетinline
, компоновщик будет жаловаться.источник
Встраивание - это предложение для компилятора, которое он может игнорировать. Это идеально подходит для небольших кусков кода.
Если ваша функция встроенная, она в основном вставляется в код, где выполняется вызов функции, а не фактически вызывает отдельную функцию. Это может помочь со скоростью, так как вам не нужно делать фактический звонок.
Это также помогает процессорам в конвейерной обработке, поскольку им не нужно перезагружать конвейер новыми инструкциями, вызванными вызовом.
Единственным недостатком является возможный увеличенный размер двоичного файла, но, пока функции невелики, это не будет иметь большого значения.
В настоящее время я склонен оставлять такие решения для компиляторов (ну, во всяком случае, умных). Люди, которые их написали, имеют тенденцию иметь гораздо более детальное знание основополагающих архитектур.
источник
Встроенная функция - это метод оптимизации, используемый компиляторами. Можно просто вставить встроенное ключевое слово в прототип функции, чтобы сделать функцию встроенной. Встроенная функция указывает компилятору вставлять полное тело функции везде, где эта функция используется в коде.
Преимущества: -
Не требует накладных расходов на вызов функции.
Это также экономит накладные расходы на переменные push / pop в стеке при вызове функции.
Это также экономит накладные расходы на обратный вызов из функции.
Это увеличивает местность ссылки, используя кэш инструкций.
После встраивания компилятор может также применить внутрипроцедурную оптимизацию, если указано. Это самое важное, так что теперь компилятор может сосредоточиться на устранении мертвого кода, может уделять больше внимания прогнозированию ветвлений, устранению индукционных переменных и т. Д.
Чтобы узнать больше об этом можно перейти по этой ссылке http://tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html
источник
Я хотел бы добавить, что встроенные функции имеют решающее значение при создании разделяемой библиотеки. Без маркировки встроенной функции она будет экспортирована в библиотеку в двоичном виде. Он также будет присутствовать в таблице символов, если экспортируется. С другой стороны, встроенные функции не экспортируются ни в двоичные файлы библиотеки, ни в таблицу символов.
Это может быть критично, когда библиотека предназначена для загрузки во время выполнения. Это может также поразить бинарно-совместимые библиотеки. В таких случаях не используйте inline.
источник
inline
при построении разделяемой библиотеки!Во время оптимизации многие компиляторы будут использовать встроенные функции, даже если вы их не отметили. Как правило, вам нужно помечать функции как встроенные, если вы знаете что-то, чего нет у компилятора, так как он может сам принять правильное решение.
источник
inline
позволяет разместить определение функции в заголовочном файле, а#include
этот заголовочный файл - в нескольких исходных файлах, не нарушая одно правило определения.источник
Вообще говоря, в наши дни любой современный компилятор, беспокоящийся о вложении чего-либо, является пустой тратой времени. Компилятор должен на самом деле оптимизировать все эти соображения для вас посредством собственного анализа кода и вашей спецификации флагов оптимизации, передаваемых компилятору. Если вас волнует скорость, скажите компилятору оптимизировать скорость. Если вам небезразлично пространство, скажите компилятору оптимизировать пространство. Как упоминалось в другом ответе, приличный компилятор будет даже встроен автоматически, если это действительно имеет смысл.
Кроме того, как заявили другие, использование inline не гарантирует ничего inline. Если вы хотите гарантировать это, вам придется определить макрос вместо встроенной функции, чтобы сделать это.
Когда встроить и / или определить макрос для принудительного включения? - Только тогда, когда у вас есть доказанное и необходимое доказанное увеличение скорости для критической части кода, которая, как известно, влияет на общую производительность приложения.
источник
Это не все о производительности. Оба C ++ и C используются для встроенного программирования, сидя на вершине аппаратного обеспечения. Если вы, например, хотите написать обработчик прерываний, вам необходимо убедиться, что код может быть выполнен сразу, без замены дополнительных регистров и / или страниц памяти. Вот когда полезен inline. Хорошие компиляторы делают некоторые «вставки» сами, когда нужна скорость, но «встроенные» заставляют их.
источник
Попал в ту же проблему с встраиванием функций в такие библиотеки. Кажется, что встроенные функции не скомпилированы в библиотеку. в результате компоновщик выдает ошибку «неопределенная ссылка», если исполняемый файл хочет использовать встроенную функцию библиотеки. (случилось со мной при компиляции исходного кода Qt с помощью gcc 4.5.
источник
Почему бы не сделать все функции встроенными по умолчанию? Потому что это инженерный компромисс. Существует как минимум два типа «оптимизации»: ускорение программы и уменьшение размера (объема памяти) программы. Встраивание вообще ускоряет вещи. Это избавляет от накладных расходов на вызов функции, избегая выталкивания и извлечения параметров из стека. Однако это также увеличивает объем памяти программы, поскольку каждый вызов функции теперь должен быть заменен полным кодом функции. Чтобы сделать вещи еще более сложными, помните, что ЦП хранит часто используемые куски памяти в кеше ЦП для сверхбыстрого доступа. Если вы сделаете образ памяти программы достаточно большим, ваша программа не сможет эффективно использовать кеш, а в худшем случае встраивание может замедлить вашу программу.
источник
Наш профессор информатики призвал нас никогда не использовать inline в программе на c ++. Когда его спросили, почему, он любезно объяснил нам, что современные компиляторы должны определять, когда использовать inline автоматически.
Так что да, inline может быть техникой оптимизации, которая будет использоваться везде, где это возможно, но, очевидно, это то, что уже сделано для вас, когда есть возможность встроить функцию в любом случае.
источник
inline
в C ++ имеет два совершенно разных значения - только одно из них связано с оптимизацией, и ваш преподаватель прав в этом отношении. Тем не менее, второе значениеinline
часто необходимо для удовлетворения правила единого определения .Вывод из другого обсуждения здесь:
Есть ли недостатки с встроенными функциями?
Видимо, нет ничего плохого в использовании встроенных функций.
Но стоит отметить следующие моменты!
Чрезмерное использование встраивания может на самом деле сделать программы медленнее. В зависимости от размера функции, ее вставка может привести к увеличению или уменьшению размера кода. Встраивание очень маленькой функции доступа обычно уменьшает размер кода, тогда как встраивание очень большой функции может значительно увеличить размер кода. На современных процессорах меньший код обычно выполняется быстрее из-за лучшего использования кэша команд. - Google Guidelines
Преимущества скорости встроенных функций имеют тенденцию уменьшаться по мере увеличения размера. В какой-то момент накладные расходы на вызов функции становятся небольшими по сравнению с выполнением тела функции, и выгода теряется - источник
Есть несколько ситуаций, когда встроенная функция может не работать:
__inline
Ключевое слово вызывает функцию , которая будет встраиваемой только при указании параметра оптимизировать. Если указан__inline
параметр «Оптимизировать», зависит от того, соблюдается или нет, параметр настройки встроенного оптимизатора. По умолчанию встроенный параметр действует при каждом запуске оптимизатора. Если вы укажете «Оптимизировать», вы также должны указать опцию noinline, если хотите, чтобы__inline
ключевое слово игнорировалось. -Источникисточник
inline
ключевое слово для определения того, стоит ли встроенный код, все приведенные выше пункты неверны. Они были бы верны, если бы компилятор использовал ключевое слово для встраивания (оно используется только для определения маркировки нескольких определений для целей связывания).