Использует ли встроенная функция больше ОЗУ или ПЗУ? и как это влияет на оперативную память микроконтроллера?

#c #embedded #inline

#c #встроенный

Вопрос:

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

Теперь я запутался, между использованием встроенной функции RAM и ROM.

Может ли кто-нибудь, пожалуйста, объединить использование встроенной функции с использованием ОЗУ и ПЗУ, особенно в контексте простого кода.

Комментарии:

1. Ваш вопрос довольно неясен, поскольку мы разбираемся не в специфике вашей системы, а в целом… Когда функция встроена, это увеличит размер исполняемых файлов ваших программ. Таким образом, предполагая, что ваш исполняемый файл хранится в ПЗУ, это увеличит объем используемой памяти ПЗУ. С другой стороны, когда функция встроена, это (как правило) уменьшает объем используемой стековой памяти. Однако, поскольку стековая память предварительно выделена, вы не увидите никаких изменений в использовании оперативной памяти, но это может позволить вам настроить систему с меньшими стеками и тем самым сэкономить оперативную память.

2. @ 4386427 да, размер исполняемого двоичного файла увеличивается с использованием inline, когда мы запускаем выполнение двоичного файла, перемещаемого из ПЗУ в ОЗУ (поправьте меня здесь, если я ошибаюсь). Если это правда, то использование оперативной памяти также увеличилось. верно?

3. Это зависит от вашей системы. Некоторые встроенные системы действительно перемещают исполняемый файл из ПЗУ в оперативную память, но другие системы могут выполняться непосредственно из ПЗУ. Поскольку я не могу знать, как работает ваша система, я не могу опубликовать реальный ответ. Чтобы ответить на ваш вопрос, нужно знать особенности системы, но общее правило таково: встроенная функция увеличивает размер исполняемого файла и снижает требования к стеку.

Ответ №1:

Ваш компоновщик сможет сгенерировать карту ссылок со сводной информацией об использовании ПЗУ и ОЗУ — вы можете выполнять сборку с встраиванием и без него и увидеть результат самостоятельно.

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

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

У вашего компилятора может быть средство принудительной встраивания, но inline ключевое слово не подходит — например, в GCC вы бы использовали __attribute__((always_inline)) атрибут функции. Однако переусердствовать с компилятором, когда дело доходит до того, что должно и не должно быть встроено, обычно является плохой идеей для современного оптимизирующего компилятора. Как правило, это позволяет принимать лучшие, более целостные решения на базе кода любого значительного размера без усилий разработчика.

Комментарии:

1. компилятор может встроиться даже без inline

Ответ №2:

Если вы запускаете свой код из флэш-памяти, длина кода не влияет на использование вашей оперативной памяти. Код будет длиннее, конечно, если функция встроена более одного раза (но это не гарантируется ключевым словом ‘inline’).

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

ключевое слово ‘inline’ — это всего лишь предложение для компилятора, если вы хотите принудительно выполнить встраивание, вам нужно использовать атрибут apripriate или pragma — для gcc __attribute__((always_inline))