Один большой пул или несколько типов определенные пулы?

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

Теперь, я нахожусь в процессе выбора между теми двумя альтернативами:

  1. Наличие пула памяти для каждого типа: это позволит действительно быстрое выделение/освобождение и минимальную фрагментацию, поскольку пул объектов уже знает размер выделенных объектов. Одна вещь, которые беспокоят меня, состоит в том, чтобы иметь несколько пулов как этот, который является отдельным, возможно, делая другое решение более эффективным...
  2. Совместное использование одного большого пула памяти всеми фабриками одного игрового представления: (использование чего-то как повышение:: пул с некоторыми функциями адаптера) тот путь я имею всю игровую память объектов, выделенную вместе, и могу иметь выделение на один бит для игры, что я уже знаю общий размер (это не всегда имеет место). Я не уверен, что это - лучшее решение, чем из-за возможной фрагментации в пуле, поскольку были бы объекты другого размера в том же пуле, но это похоже на более легкий для анализа памяти и другой фиксации задач.

Теперь, у меня был некоторый опыт реальных миров с, таким образом, я не испытан с B и хотел бы некоторый совет относительно тех решений для длительного проекта. Какое решение кажутся лучше для длительного проекта и почему? (Отметьте: пул действительно необходим в этом случае, потому что игровая модель используется для игры, редактирующей также, таким образом, будет партия выделения/освобождения небольших объектов).

Редактирование для разъяснения: я использую C++, если (это еще не ясно),

9
задан Klaim 27 December 2009 в 00:22
поделиться

6 ответов

Правильный ответ специфичен для вашего проблемного домена. Но в проблемных доменах, которые я работаю, первым обычно является тот, который мы выбираем.

Я делаю код в реальном или близком к реальному времени. Редактирование и воспроизведение аудио в основном. В этом коде мы обычно не можем позволить себе выделять память из кучи вниз в движке воспроизведения. В большинстве случаев, malloc возвращается достаточно быстро, но иногда нет. И это иногда имеет значение.

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

В качестве запасного варианта для необычных случаев; когда кому-то нужно выделить из специального пула и он пуст - мы выделим кусок общей памяти (несколько объектов) и добавим его в специальный пул. Как только выделение является частью специального пула, оно НИКОГДА не возвращается в общий пул до тех пор, пока приложение не выйдет или не запустит новый проект.

Хороший выбор исходного размера и максимального размера специальных пулов является важной частью настройки приложения.

9
ответ дан 4 December 2019 в 11:05
поделиться

Одна из проблем, с которой вы столкнетесь, заключается в том, что реализация STL позволяет предположить, что два аллокатора одного типа эквивалентны. Это является причиной того, что Boost.Pool использует только один пул (технически он использует разные пулы для каждого типа). Т.е. вашим аллокаторам не разрешается иметь никаких нестатических членов в общем случае. Если вы делаете видеоигру и знаете, что ваша реализация STL не имеет этой проблемы, то не волнуйтесь об этом - однако могут быть проблемы с list::splice и std::swap на контейнерах.

.
4
ответ дан 4 December 2019 в 11:05
поделиться

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

Первый метод наиболее распространен, и как тот, кто сделал оба, это, вероятно, единственный способ, который практичен, если ты не хочешь тратить много времени и энергии на проблему, чем она, вероятно, стоит для тебя. Второй способ лучше, потому что он более общий и в то же время может быть приспособлен к вашим точным потребностям, но это много работы, а не то, в чем можно легко прыгнуть.

.
4
ответ дан 4 December 2019 в 11:05
поделиться

Одно из возможных решений - что-то между 1. и 2.

Используйте пулы для малых объектов: один пул на размер объекта. В этом случае вы можете легко найти пул, сохранив указатели в массиве.

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

Обратите внимание на boost::pool. При тестировании производительности boost::pool проверяется не только выделение, но и дилексирование. Я испытал, что boost::pool и boost::fast_pool время дилокации может быть экстремально большим. Мой случай состоял из распределений и де-локаций маленьких объектов разного размера в одном пуле

.
2
ответ дан 4 December 2019 в 11:05
поделиться

У меня нет конкретного опыта работы с рассматриваемым менеджером памяти, но вот некоторые общие рекомендации, которые могут помочь:

  • Если вы не ожидаете нехватки памяти, то лучше всего использовать Вариант 1, потому что в его состоянии он быстр (быстрее 2? ), а наличие отдельных пулов облегчит обнаружение проблем с распределением/удалением/буфером (если предположить, что менеджер пула имеет достойные возможности обнаружения ошибок).
  • Если память может быть проблемой (как в вашей игре будет занимать много памяти по сравнению с общедоступной памятью целевой платформы), то наличие одного большого пула обеспечит более эффективное использование памяти. Кроме того, если вы не можете точно предсказать средние и максимальные требования к памяти на пул, это лучший выбор, если менеджер памяти может динамически увеличивать пулы памяти (а в идеале, динамически освобождать блоки из пула, а также). Единственным недостатком до 2, который я вижу, является то, что он может быть медленнее (это так?), и ошибки в управлении памятью может быть труднее обнаружить.

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

.
0
ответ дан 4 December 2019 в 11:05
поделиться

Вообще-то, я возьму 2. Могу привести пример из ядра linux. В ядре объекты dentry(directory entry) и inode должны дольше кэшироваться в памяти для лучшей отзывчивости к пользователям. Так как объект inode зависит от файловой системы, каждая файловая система будет создавать свой пул объектов. Еще одна вещь, которую вы можете сделать, если объекты похожи, это абстрагироваться от объектов и хранить общие атрибуты в одном абстрактном объекте, а также хранить специфическую для объекта информацию с помощью контейнера. За полной идеей обращайтесь к приведенному ниже коду.

http://lxr.linux.no/linux+v2.6.32/fs/ext2/super.c#L149

0
ответ дан 4 December 2019 в 11:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: