Обновить

Комментарии 5

каждая моя попытка "вкатится" во все эти нововведения С++ заканчиваются пониманием что мне и на Си хорошо

спасибо за статью, прочитал с удовольствием

Спросил у нейросети на своем проекте игры - ИИ сказала(вкратце): "нафиг тебе эти сложности, сиди дальше на stl. Эффект будет околонулевой на ECS. Лучше используй PGO".

Подробный отчет

Текущее состояние

  • Проект использует std::vector (~150 мест), std::unordered_map (~40), std::string (200+) и std::function (17)

  • Сборка: MSVC /O2 (без PGO, без LTCG)

  • EnTT управляет памятью ECS самостоятельно

  • Нет кастомных аллокаторов

    Оправдан ли EASTL? Нет, выигрыш в производительности будет от незначительного до нулевого для этого проекта:

    1. Горячий путь (per-frame) не нагружает STL-контейнеры. EnTT управляет entity/component storage internally. Основной цикл: input → ECS systems (iterate sparse sets) → render. std::vector используется в основном в инициализации, UI, данных — не в критических 60 FPS участках.

    2. std::vector уже эффективен. EASTL даёт выигрыш:

  • Кастомных аллокаторах (можно сделать и без EASTL)

  • fixed_vector/small_vector (маленькие буферы на стеке)

  • Отключении MSVC iterator debugging (отключается флагом ITERATORDEBUG_LEVEL=0)

    3. std::unordered_map — спорно. Хэш-таблицы EASTL быстрее за счёт кастомного аллокатора и simpler design, но в проекте мапы используются для lookup по строковым ID при загрузке/событиях, не каждый кадр.

    4. Цена внедрения:

  • Новая зависимость в CMake (EASTL — нетривиальная сборка)

  • Время компиляции увеличится

  • Хуже визуализация в дебаггере MSVC

  • Нюансы: eastl::string не взаимозаменяем с std::string, нужны врапперы

  • Кодовая база станет менее портируемой (Linux/MSVC already поддерживают)

  • EnTT не использует EASTL — он всё равно будет на std::

    Что реально даст выигрыш:

  • PGO (/LTCG /GL /GENPROFILE)

  • Frame allocator (через pmr или свой)

  • reserve() на векторах.

  • Кэширование unordered_map lookup (ID → ptr).

  • std::function на FunctionPtr там где можно.

    Резюме: EASTL не стоит добавлять. Если хотите оптимизировать — начните с PGO и замера профиля. Если нужен кастомный аллокатор для временных данных, std::pmr::monotonic_buffer_resource решит это без новой библиотеки.

Почесал репу и пошел узнавать что это за PGO. Вот такие дела...

200 мест использования строчек это действительно очень мало, вам и PGO не нужен, видимо игра очень маленькая. Для понимания о чем я тут вообще говорил, я бы посоветовал для начала подключить Tracy (это не сложно) и собрать его в режиме трекинга памяти, и посмотреть что происходит за 10 секунд игрового времени с системой.

Да, игра маленькая, но ресурсоемкая(сурвиворлайк) - сотни и тысячи врагов на экране и кучу снарядов, взаимодействующих с ними, так что любая оптимизация важна. За Tracy спасибо.

P.S. не туда написал.

Отличный цикл статей. А то всё больше нейрослопа здесь. Единственное, что бросилось в глаза, различия интерфейсов аллокаторов STL и EASTL. Комитет C++ идёт по пути максимально слабых ограничений и, как ни странно, максимальной рантайм эффективности. Поэтому, передача флагов в качестве рантайм параметра для диспатча на арену явно немного снижает перформанс и увеличивает вероятность ошибок. Это напоминает C с классами.

Мне кажется, здесь больше подошёл бы folly подход статической диспечеризации. Андрей Александреску на лекции показывал его на объектах разных размеров, которые выделялись разными кучами, чтобы уменьшить фрагментацию. В вашем случае было бы уместно разделить R и RW объекты на два разных аллокатора.

Ну, вообщем, вы и пишете в конце, что STL потихонечку закрывает дыры. Слишком медленно, да. Ну плюс ещё boost, и нет никаких проприетарных решений

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации