Как такие игры, как GTA IV, не фрагментируют кучу? - PullRequest
18 голосов
/ 14 января 2011

Меня интересует тип управления памятью, который могла бы использовать игра, подобная GTA IV, учитывая, что она должна очень быстро создавать и удалять множество объектов. Как сделать, чтобы избежать фрагментации кучи и прочего. Если бы кто-то мог указать мне правильное направление, я был бы очень благодарен.

Ответы [ 6 ]

23 голосов
/ 14 января 2011

Они используют такие вещи, как пул памяти , специальные распределители и специализированные классы контейнеров.

  1. Распределитель Hoard Memory для многопоточных программ.
  2. Версия советника STL . Содержит распределители, контейнеры,
7 голосов
/ 14 января 2011

Хотя этот документ не относится конкретно к играм, он предоставляет хороший обзор типов пользовательских распределителей памяти, которые люди часто используют в приложениях на C и C ++ для повышения производительности (и это немного предостерегающая история).

Пересмотр пользовательского выделения памяти , Berger, Zorn & McKinley, OOPSLA 2002

Программисты, надеющиеся добиться улучшения производительности, часто используют пользовательскиераспределители памяти.В этом углубленном исследовании рассматриваются восемь приложений, использующих пользовательские распределители.Удивительно, что для шести из этих приложений современный распределитель общего назначения (распределитель Lea) работает так же хорошо или лучше, чем пользовательские распределители.В двух исключениях используются регионы, которые обеспечивают более высокую производительность (улучшение до 44%).Регионы также уменьшают нагрузку на программиста и устраняют источник утечек памяти.Однако мы показываем, что неспособность программистов освободить отдельные объекты внутри регионов может привести к значительному увеличению потребления памяти.Хуже того, это ограничение исключает использование областей для общих идиом программирования, снижая их полезность.Мы представляем обобщение универсальных и региональных распределителей, которые мы называем пожинаниями.Рипы представляют собой комбинацию областей и куч, обеспечивая полный диапазон семантики областей с добавлением удаления отдельных объектов.Мы показываем, что наша реализация reaps обеспечивает высокую производительность, опережая другие распределители с региональной семантикой.Затем мы используем тематическое исследование, чтобы продемонстрировать космические преимущества и преимущества программных разработок, полученных на практике.Наши результаты показывают, что программисты, которым нужны быстрые регионы, должны использовать reaps, и что большинство программистов, рассматривающих пользовательские распределители, должны вместо этого использовать распределитель Lea.

6 голосов
/ 14 января 2011

Существует две очень хорошие реализации malloc для многопоточных реализаций:

  • tcmalloc: от Google
  • jemalloc: используется Apache (например)

Вот статья в Facebook об улучшении jemalloc .Это примерно в 5 раз быстрее, чем распределитель памяти Хоарда в текущем топ-ответе:)

5 голосов
/ 14 января 2011

Создание и уничтожение множества объектов действительно быстро не обязательно означает фрагментацию кучи. Часто, если объекты имеют одинаковый размер, место, освобожденное одним, может быть выделено для следующего.

Часто, даже в качестве оптимизации, программа может не освобождать и не удалять память для объектов, а сохранять старые в пуле и просто захватывать их и перезаписывать содержимое для создания «нового» объекта.

1 голос
/ 14 января 2011

Во многих играх используются некоторые из перечисленных здесь распределителей памяти.dlmalloc - тот, который мы использовали с большим успехом (мы связали его с Lua).Вы можете получить информацию о dlmalloc здесь .

Еще одна вещь, которую я хотел бы упомянуть, это то, что не все игры должны использовать динамическое распределение памяти.Мы использовали mempools и статические области памяти для большинства наших данных игрового процесса.Только системы, которые требуют динамического размещения, делают это (Lua и некоторые сторонние библиотеки).Все остальное, что мы делаем, исходит из статических буферов.Мы также не используем STL в коде игры, что помогает ограничить «повреждение» фрагментации памяти.

1 голос
/ 14 января 2011

Я думаю, что поскольку их объекты в основном имеют одинаковый размер, они могут использовать некоторый менеджер внутренней памяти, который фактически не освобождает память, но помечает ее как доступную, и в следующий раз, когда выделяется кусок ~ размера, он возвращает его.

...