Оперативная память стоимость ввода функций

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

Это правда или, если это не так, каков максимальный рекомендуемый уровень вложенности функций во время выполнения?

, 👍2

Обсуждение

http://wiki.c2.com /?Преждевременная оптимизация, @Juraj


2 ответа


Лучший ответ:

2

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

Я бы не сказал "значительный", но некоторая оперативная память используется, да.

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

Это только временные выделения, которые снова высвобождаются при выходе функции.

В зависимости от вашей программы "стек вызовов" может быть незначительным по сравнению с локальными переменными.

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

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

Основная причина сглаживания программы обычно заключается в скорости выполнения, а не в использовании памяти.

,

Кроме того, если функция вызывается только в одном месте или очень короткая, компилятор попытается встроить функцию, сводя на нет "стоимость", связанную с вызовом функции., @Gerben


2

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

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

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

inline __attribute__((always_inline))

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

,