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