#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))