Что не так с использованием подставляемых функций?

AFAIK, No.

'typedef' помогает вам настроить «псевдоним» на существующий тип данных. Напр. typedef char chr;

#define - это директива препроцессора, используемая для определения макросов или общих подстановок шаблонов. Напр. #define MAX 100, заменяет все вхождения MAX со 100

36
задан jonrsharpe 19 February 2015 в 21:51
поделиться

10 ответов

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

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

я также рекомендовал бы делать функции inline'd очень небольшими - преимущества скорости подставляемых функций имеют тенденцию уменьшаться, поскольку функция увеличивается в размере. В какой-то момент издержки вызова функции становятся маленькими по сравнению с выполнением тела функции, и преимущество потеряно.

21
ответ дан Alan 27 November 2019 в 06:03
поделиться

Это могло увеличить размер исполняемого файла, и я не думаю, что компиляторы будут всегда на самом деле заставлять их встроить даже при том, что Вы использовали встроенное ключевое слово. (Или действительно ли это наоборот, как какой сказанный Vaibhav?...)

я думаю, что обычно хорошо, если функция имеет только 1 или 2 оператора.

Редактирование: Вот то, что документ linux CodingStyle говорит об этом:

Глава 15: встроенная болезнь

Там, кажется, общее неправильное восприятие, что gcc имеет волшебство, "делают меня быстрее" опцией ускорения названный "встроенным". В то время как использование встраивает, может быть соответствующим (например, как средство замены макросов, см. Главу 12), это очень часто не. Богатое использование встроенного ключевого слова приводит к намного большему ядру, которое в свою очередь замедляет систему в целом вниз, из-за большего icache места для ЦП и просто потому что существует меньше памяти, доступной для pagecache. Просто думайте об этом; мисс pagecache вызывает поиск на диске, который легко берет 5 миллисекунд. Существует МНОГО циклов CPU, которые могут войти в эти 5 миллисекунд.

А разумное эмпирическое правило не должно помещать встроенный в функции, которые имеют больше чем 3 строки кода в них. Исключением к этому правилу являются случаи, где параметр, как известно, является постоянным временем компиляции, и в результате этой постоянности Вы знаете , компилятор будет в состоянии оптимизировать большую часть Вашей функции далеко во время компиляции. Для хорошего примера этого более позднего случая посмотрите kmalloc () подставляемая функция.

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

14
ответ дан Community 27 November 2019 в 06:03
поделиться

Я соглашаюсь с другими сообщениями:

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

, точка трети А - он, может вынудить Вас представить детали реализации в своих заголовках, .e.g.,

class OtherObject;

class Object {
public:
    void someFunc(OtherObject& otherObj) {
        otherObj.doIt(); // Yikes requires OtherObj declaration!
    }
};

Без встроенного предописание OtherObject было всем, в чем Вы нуждались. Со встроенным для Вашего заголовка нужно определение для OtherObject.

4
ответ дан maccullt 27 November 2019 в 06:03
поделиться

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

4
ответ дан Bronek 27 November 2019 в 06:03
поделиться

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

, Если Вы действительно, действительно хотите заставить что-то встроить, если Вы на самом деле представили его и посмотрели на дизассемблирование, чтобы гарантировать, что переопределение эвристики компилятора на самом деле имеет смысл, тогда это возможно:

  • В VC ++, используйте __ forceinline ключевое слово
  • В GCC, используйте __ атрибут __ ((always_inline))

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

4
ответ дан Niall 27 November 2019 в 06:03
поделиться

Я сомневаюсь относительно него. Даже компилятор автоматически встраивает некоторые функции для оптимизации.

2
ответ дан Vaibhav 27 November 2019 в 06:03
поделиться

Я не знаю, имел ли мой ответ отношение к вопросу, но:

Быть очень осторожны относительно встроенных виртуальных методов! Некоторые ошибочные компиляторы (предыдущие версии Visual C++, например) генерировали бы встроенный код для виртуальных методов, где стандартное поведение состояло в том, чтобы сделать, только спускаются по дереву наследования и называют соответствующий метод.

2
ответ дан Stacker 27 November 2019 в 06:03
поделиться

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

Решение, когда функция является достаточно небольшой, что встраивание увеличит производительность, довольно хитро. Руководство по стилю C++ Google рекомендует только встроить функции 10 строк или меньше.

1
ответ дан Nick 27 November 2019 в 06:03
поделиться

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

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

с VC ++ компилятор Вы можете сверхъязь это решение при помощи __forceinline

ТАК в целом: Используйте встроенный, если Вы действительно хотите иметь функцию в заголовке, но в другом месте существует мало точки потому что, если Ваша попытка получить что-нибудь от нее, хороший компилятор будет заставлять ее встроить для Вас так или иначе.

1
ответ дан greatwolf 27 November 2019 в 06:03
поделиться

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

0
ответ дан Mladen Janković 27 November 2019 в 06:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: