В настоящее время я нахожусь на стадии разработки архитектуры на основе компонентов в C ++.
Мой текущий дизайн включает в себя использование таких функций, как:
std::vector
sstd::shared_ptr
для хранения компонентовstd::dynamic_pointer_cast
std::unordered_map<std::string,[yada]>
Компоненты будут представлять данные и логику различных элементов, которые необходимы в игровом программном обеспечении, таком как графика, физика, искусственный интеллект, аудио и т. Д.
Я везде читал, что ошибки в кэше сильно влияют на производительность, поэтому я провел несколько тестов, которые заставили меня поверить, что, действительно, это может замедлить работу приложения.
Я не смог протестировать вышеупомянутые языковые возможности, но во многих местах сказано, что они, как правило, стоят дорого, и их следует избегать, если это возможно.
Поскольку я нахожусь на стадии проектирования архитектуры, и они будут включены в ядро проекта, я должен попытаться найти способы избежать их сейчас, так как будет очень трудно изменить это позже, если есть производительность вопросы?
Или я просто застрял в преждевременной оптимизации?
источник
the answer to this question is almost always a resounding "YES !!"
. Я все еще чувствую, что лучше сначала заставить его работать, а потом оптимизировать, но YMMV, у каждого свое мнение, и все они верны, и только ОП может действительно ответить на его собственный - субъективный - вопрос.Ответы:
Не читая ничего, кроме названия: Да.
После прочтения текста: да. Хотя это правда , что карты и общие указатели и т.д. , не выполняют также кэш-накрест, вы наверняка обнаружите, что вы хотите использовать их - насколько я понимаю - это не узкий и не будешь проходить или эффективно использовать кэш независимо от структуры данных.
Напишите программное обеспечение, избегая самых глупых ошибок, затем протестируйте, затем найдите узкие места и оптимизируйте!
Fwiw: https://xkcd.com/1691/
источник
Я не знаком с C ++, но в целом это зависит.
Вам не нужно преждевременно оптимизировать изолированные алгоритмы, где вы можете легко оптимизировать, когда дело доходит до этого.
Однако вам необходимо получить общий дизайн приложения для достижения желаемых ключевых показателей эффективности.
Например, если вам нужно спроектировать приложение для обслуживания миллионов запросов в секунду, вам нужно подумать о масштабируемости приложения при его разработке, а не о том, чтобы приложение работало.
источник
Если вам нужно спросить, тогда да. Преждевременная оптимизация означает оптимизацию, прежде чем вы убедитесь, что существует значительная проблема производительности.
источник
ECS? На самом деле, я полагаю, что это не будет преждевременным, если так много думать о ориентированной на данные стороне проекта и оценивать различные повторы, потому что это может повлиять на ваш дизайн интерфейса , а последнее очень дорого менять в конце игра. Кроме того, ECS просто требует большой работы и обдумывания заранее, и я думаю, что стоит потратить часть этого времени, чтобы убедиться, что это не приведет к печальному падению производительности на уровне дизайна, учитывая то, как это будет в основе вашей работы. весь долбанный двигатель. Эта часть смотрит на меня:
Даже с небольшими оптимизациями строк у вас есть контейнер переменного размера (строки) внутри другого контейнера переменного размера (unordered_maps). На самом деле, небольшая строковая оптимизация может быть настолько же вредной, насколько и полезной в этом случае, если ваша таблица очень разреженная, поскольку небольшая строковая оптимизация подразумевает, что каждый неиспользуемый индекс хеш-таблицы будет по-прежнему использовать больше памяти для оптимизации SS (
sizeof(string)
будет намного больше) до такой степени, что общие накладные расходы памяти вашей хеш-таблицы могут стоить больше, чем все, что вы храните в ней, особенно если это простой компонент, такой как компонент позиции, в дополнение к большим потерям кеша с огромным шагом получить от одной записи в хеш-таблице к следующей.Я предполагаю, что строка является своего рода ключом, например, идентификатором компонента. Если это так, это уже делает вещи значительно дешевле:
... если вы хотите иметь возможность иметь удобные для пользователя имена, которые могут использовать сценарии, например, интернированные строки могут дать вам лучшее из обоих миров.
Тем не менее, если вы можете сопоставить строку с достаточно низким диапазоном плотно используемых индексов, то вы можете просто сделать это:
Причина, по которой я не считаю это преждевременным, заключается в том, что, опять же, это может повлиять на ваш дизайн интерфейса. Смысл DOD не должен состоять в том, чтобы пытаться придумать наиболее эффективные представления данных, которые можно себе представить за один раз (как правило, это должно быть достигнуто многократно по мере необходимости), а в том, чтобы думать о них достаточно, чтобы разрабатывать интерфейсы на вершине, чтобы работать с этим. данные, которые оставляют вам достаточно места для профилирования и оптимизации без каскадных изменений дизайна.
В качестве наивного примера, программное обеспечение для обработки видео, которое связывает весь свой код с этим:
Не удастся продвинуться далеко без потенциально эпического переписывания, так как идея абстрагирования на уровне одного пикселя уже чрезвычайно неэффективна (
vptr
сама по себе часто будет стоить больше памяти, чем весь пиксель) по сравнению с абстрагированием на уровне изображения (который будет часто представляют миллионы пикселей). Поэтому заранее продумайте свои представления данных, чтобы вам не приходилось сталкиваться с таким кошмарным сценарием, а в идеале - больше, но здесь я думаю, что стоит подумать об этом заранее, поскольку вы не хотите создавать сложный двигатель вокруг вашей ECS и обнаружить, что сама ECS является узким местом в пути, которые требуют от вас что-то изменить на уровне проектирования.Что касается ошибок кэша ECS, то, по моему мнению, разработчики часто слишком стараются сделать их ECS-дружественными к кешу. Он начинает приносить слишком мало денег, чтобы попытаться получить доступ ко всем вашим компонентам совершенно непрерывным образом, и часто подразумевает копирование и перетасовку данных повсюду. Обычно достаточно достаточно, скажем, просто использовать индексы компонентов радикальной сортировки до доступа к ним, чтобы вы обращались к ним таким образом, чтобы, по крайней мере, вы не загружали область памяти в строку кэша только для ее удаления, а затем загружали все снова и снова в одном цикле, чтобы получить доступ к другой части той же строки кэша. И ECS не должен обеспечивать удивительную эффективность по всем направлениям. Это не так, как система ввода извлекает из этого столько же, сколько физическая система или система рендеринга, поэтому я рекомендую стремиться к «хорошему». эффективность по всем направлениям и «отлично» только в тех местах, где это действительно нужно. Тем не менее, использование
unordered_map
иstring
здесь достаточно легко избежать.источник