cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

API для ресурсов в С++ #477

Open Izaron opened 2 years ago

Izaron commented 2 years ago

API ресурсов

Идея в том, чтобы реализовать в C++ понятие "ресурсов" (или "архива"). API для них будет в условном std::resources или std::archive.

"Ресурс" - это файл любого расширения (изображения, звук, текст, видео, 3d-модельки, ..., набор байт), который с использованием нового API можно было бы "вшить" в исполняемый бинарник приложения (и не только туда, но об этом позже), и не загружать его "руками" после старта приложения, откуда-то из внешней директории.

API разбивается на 2 части:

  1. Указание файлов для "ресурсов" и настроек по их хранению - compile-time.
  2. Обращение к этим файлам - run-time.

Условный пример кода по частям:

  1. В неком из .cpp-файлов проекта определяется статический объект апишки, который constexpr-ово инициализируется, и куда мы указываем все директории/файлы для зашивания, кодек их сжатия (более мощный уменьшит бинарь, но будет чуть медленнее), и т.д.:
    static constinit const auto resources_holder = std::resources
    ::load_resources({"images/", "models/", "license/MIT.txt"});
  2. В рантайме можно обращаться к файлам:
    const std::span<std::byte> logo = resources_holder.get_resource("images/logo.png");

Техническая реализация (кратко, отбросив мелочи)

Если говорить про большинство Unix-ов: для объектных файлов и бинарей используется формат ELF. Для хранения ресурсов подходит секция .rodata. Эту секцию загрузчик во время старта приложения загружает в read-only режиме и держит в RAM.

Значит, в процессе компиляции перед линковкой, объектный файл того .cpp, где создается объект из 1 пункта, должен в .rodata содержать массив байт - загруженные ресурсы. Отсюда следует, что динамические и статические библиотеки могут являться носителями ресурсов наравне с бинарями.

Польза

Более быстрый запуск приложений, которые читают всякие файлы при старте. Более cache-friendly по сравнению с файлами, которых загрузили куда попало в кучу. Меньше головной боли для небольших приложений, которые имеют внешние ресурсы.

ML-приложения могут проще обращаться к своим моделькам из RAM.

Особенно неплохо будет для игр, где обычно много ресурсов (кроме тех, где они весят суммарно 100гб и то загружаются, то выгружаются из RAM).

Smertig commented 2 years ago

https://github.com/cplusplus/papers/issues/28

Izaron commented 2 years ago

cplusplus/papers#28

Спасибо. Бывает)

apolukhin commented 2 years ago

Работа ведётся в https://wg21.link/p1040