Как можно предварительно инициализировать структуры данных в памяти для программ на основе ПЗУ?
Рассмотрим STL unordered_map
, Один и тот же класс шаблона используется как для хеш-таблиц, генерируемых во время выполнения, так и для хеш-таблиц, состоящих из значений констант во время компиляции. В то время как последние версии C++ добавляют constexpr
его поддержка не распространяется на более сложные операции, включающие бесплатное хранилище, следовательно, создание хеш-таблицы из констант времени компиляции должно происходить во время выполнения, что делает его столь же дорогим, как и создание любой другой хеш-таблицы во время выполнения.
В идеале, идеальный компилятор должен видеть это и предварительно оценивать конструкцию хеш-таблицы во время компиляции и встраивать ее непосредственно в программу.
Это заставило меня задуматься о ретрокомпьютерах и микроконтроллерах, которые, по-видимому, имели бы свое программное обеспечение, написанное на C или C++, учитывая стоимость разработки сборки: эти среды часто имеют ограниченную оперативную память, но много ПЗУ, и такие структуры данных в памяти (такие как unordered_map
), конечно, может быть предварительно сгенерирован и сохранен в ПЗУ все во время компиляции.
Как уже упоминалось, язык C++ не поддерживает это для нетривиальных constexpr
, Я понимаю, что вы могли бы взломать это вместе, предполагая, что вы можете основывать свою сложную структуру данных на типе массива или уменьшить ее до constexpr
- или напишите все это в сборке и вручную устанавливая каждый байт структуры в hex-редакторе и надеясь, что он соответствует представлению вашего компилятора struct
типы (например).
Как это делается сегодня? И как это было во времена 16-битных и 32-битных игровых приставок, где такты ОЗУ и ЦП были выше? Я особенно заинтересован в том, чтобы узнать об играх на основе картриджей с ПЗУ, где структуры сразу становятся доступны в виде необработанной памяти.
2 ответа
В микроконтроллерных системах C++ все конструкторы объектов со статической продолжительностью хранения вызываются во время загрузки, примерно в точке, где .data
а также .bss
Сегменты etc инициализируются до вызова main(). Это одна из нескольких причин, почему C++, как правило, не подходит для таких систем - он фактически выполняет код приложения на этапе запуска.
В тех приложениях, о которых вы упоминаете, например в старых видеоиграх, таблицы, скорее всего, рассчитаны заранее и записаны в ПЗУ. Я сомневаюсь, что C++ широко использовался для таких игр, или, если это было так, они использовали ограниченный поднабор языка.
unordered_map
это крайне неэффективный тип структуры данных, который вы никогда не будете использовать в таких условиях. Более разумные вещи, такие как массивы и деревья, легко сделать с помощью статических инициализаторов. Если это становится более сложным, вы пишете программу для генерации C, содержащую требуемые статические инициализаторы, и запускаете ее в системе, которая может это обработать.
В "Старые дни" - начале 80-х и 90-х годов оперативная память была очень дорогой, флэш-память была дорогой и ненадежной, но ПЗУ, особенно ПЗУ с маской, было дешевым.
Консоли для видеоигр обычно запускали игры из ПЗУ, используя крошечный объем оперативной памяти в качестве оперативной памяти. Например, исходная консоль NES имела 2048 байт ОЗУ.
Скомпилированные языки не использовались при разработке игр, поэтому, чтобы ответить на ваш исходный вопрос, структуры данных были инициализированы копированием пустой структуры из ПЗУ в ОЗУ.