C Встроенные функции и использование памяти - PullRequest
6 голосов
/ 11 ноября 2008

Если я использую встроенные функции, увеличивается ли использование памяти?

Ответы [ 8 ]

8 голосов
/ 11 ноября 2008

Существует два вида использования памяти, на которые влияют встроенные функции:

размер кода & mdash; В общем, встроенный код увеличивает объем используемой памяти для загрузки вашей программы. Это потому, что вокруг вашей программы будет разбросано несколько копий сгенерированного кода. Однако это не всегда так - если ваша встроенная функция использовалась только один раз, изменений мало, и если встроенная функция очень мала, вы можете получить чистое уменьшение размера кода, удалив служебную информацию при вызове функции. Кроме того, функция может быть уменьшена в размере оптимизатором, который может удалить код, который не используется в конкретном встроенном вызове.

использование стека & mdash; Если ваши встроенные функции имеют много локальных переменных, вы можете использовать больше стекового пространства. В Си компилятор обычно выделяет пространство стека для функции один раз при входе в функцию. Это должно быть достаточно большим, чтобы содержать все локальные переменные, которые не хранятся в регистрах. Если вы вызываете функцию вне линии, стек для этой функции используется до тех пор, пока она не вернется, когда снова будет освобождена. Если вы встраиваете функцию в функцию, то это пространство стека будет использоваться в течение всей жизни функции uber.

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

6 голосов
/ 11 ноября 2008

Есть еще один момент, который вы должны рассмотреть:

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

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

2 голосов
/ 11 ноября 2008

Это действительно не подлежит ответственности в общем случае.

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

Компилятор сделает все возможное для оптимизации кода; использование in-lining - всего лишь один из инструментов для этого. Таким образом, встраивание коротких функций сделает код меньше (так как вам не нужно устанавливать параметры для вызова или получать возвращаемое значение. Но даже с длинными функциями ответ не является абсолютным.

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

По сути, компилятор анализирует и определяет наилучший курс действий.

Заключение. Не беспокойся об этом. Компилятор умнее вас и будет делать все правильно.

2 голосов
/ 11 ноября 2008

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

1 голос
/ 11 ноября 2008

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

0 голосов
/ 11 ноября 2008

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

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

Хотя встроенное объявление в c ++ является бесплатным и происходит автоматически, когда функция определена в объявлении, в c оно ограничено следующими правилами: *

  1. В C любая функция с внутренней связью может быть объявлена ​​встроенной, но функция с внешней связью имеет ограничения для встроенной.

  2. Если ключевое слово inline используется в объявлении функции, то определение функции должно присутствовать в той же единице перевода.

встроенный тип данных имя_функции (аргументы)

Этот код работает на 30% быстрее, чем не встроенная функция, остальное зависит от скорости процессора.

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

Встроенное объявление, хотя и разрушает порядок оценки, но не делает функцию внутренней. Функция все еще внешняя.

0 голосов
/ 11 ноября 2008

Для вызова функции требуется несколько инструкций процессора.

Обычно вам требуется инструкция PUSH для каждого аргумента функции, инструкция CALL для вызова функции и часто другая инструкция, которая очищает стек после вызова функции.

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

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

Тем не менее, вставка предназначена для случаев, когда ваш профилировщик говорит вам, что вы должны.

0 голосов
/ 11 ноября 2008

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

Почему ты спрашиваешь? Обычно вы позволяете компилятору определять, должна ли функция быть встроенной или нет; обычно он может сделать лучший вызов, учитывая размер и сложность функции.

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