Оптимизация скорости с использованием const, static, constexpr и т. д. в функции

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

У меня есть такая строка:

const char trigs[] = "aAbBcCdDeEfFgGhHiIjJ";

Если это глобально, результирующая статистика компиляции показывает:

Sketch uses 3418 bytes (10%) of program storage space. 
Global variables use 431 bytes (21%) of dynamic memory.

Когда это внутри функции (для ограничения области действия), я получаю:

Sketch uses 3470 bytes (10%) of program storage space. 
Global variables use 431 bytes (21%) of dynamic memory.

Дополнительное пространство программы составляет 52 байта, что больше размера переменных, поэтому там должен быть дополнительный код. Возможно, это связано с проверками инициализации... но почему? Разве const уже не известен? Если есть разница в том, где оно хранится, почему не меняется пространство глобальных переменных?

Если я добавлю к этому префикс static const, я вернусь к первому поведению (3418/431).

Поэтому, я полагаю, непосредственный ответ - просто использовать static const. Но мне все еще интересно, что происходит. Может кто-нибудь объяснить?

, 👍-1

Обсуждение

Можете ли вы показать нам весь свой эскиз?, @VE7JRO

@VE7JRO - Я не думаю, что это практично. Если важно увидеть больше контекста, я мог бы попытаться создать минимальный набросок, иллюстрирующий это, но сейчас это кажется довольно простым. Действительно ли необходимо больше контекста?, @Jim Mack

with const char* trigs = "aAbBcCdDeEfFgGhHiIjJ"; размер эскиза всегда одинаков для глобального или локального значения со статическим или без статического. если я вызову функцию дважды, лучше использовать локальную версию без статики, @Juraj

Чтобы оптимизировать скорость, добавьте это в начало вашего скетча: #pragma GCC оптимизировать("-O3"), @Jot


1 ответ


0

const char trigs[] является автоматическим — он выделяется в стеке во время входа в функцию — и должен инициализироваться при каждом вызове. Используемый для этого литерал хранится в пространстве глобальных переменных, поэтому распределение глобальных переменных не меняется.

static const char trigs[] выделяется в пространстве глобальных переменных и используется на месте. Однако область действия символов по-прежнему локальна, поэтому trigs[] не виден за пределами функции.

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

,

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

это не ответ. вопрос был: почему, если он константный и значение известно во время компиляции, он не оптимизируется, как статический?, @Juraj

@Юрай - Это был мой настоящий вопрос, но, прочитав больше, я понял, что «const» здесь не означает то, что я наивно думал. Здесь trigs[] — это такая же переменная, как и любая другая: атрибут const просто делает ее доступной только для чтения. Это не интуитивно понятно для человека, пришедшего из языка, в котором есть «настоящие» константы, но именно так написана спецификация., @Jim Mack