Как подстраивать размер пула под текущие нужды?

Программирование на Юнити.

Как подстраивать размер пула под текущие нужды?

Сообщение Инженер 15 апр 2020, 14:54

Допустим, обычно во время игры нужно 10 экземпляров какого-то префаба. Но иногда случайно может потребоваться 20 экземпляров. В этом случае пул досоздаст 10 объектов. Если они не будут уничтожены, то мы будем хранить их в памяти до конца игры, даже если 20 штук больше никогда не понадобятся. Из-за таких ситуаций игра будет использовать все больше излишней памяти.

Как можно решить эту проблему?

Как определить текущие нужды, например, что 10- это нормально, а 20- много?

Счетчик. Если будут тысячи пулов, предполагаю, что отсчитывать для каждого время в каждом кадре будет накладно.
Инженер
UNIт
 
Сообщения: 88
Зарегистрирован: 22 май 2016, 11:13

Re: Как подстраивать размер пула под текущие нужды?

Сообщение 1max1 15 апр 2020, 15:03

В какой-то момент просто очищай пул от неиспользуемых объектов.
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

Re: Как подстраивать размер пула под текущие нужды?

Сообщение Инженер 15 апр 2020, 15:49

1max1 писал(а):В какой-то момент просто очищай пул от неиспользуемых объектов.


Так просто? Может тогда и сами пулы уничтожать? Зачем всю игру будет существовать какой-нибудь пустой пул редкого префаба, который может больше не встретиться. Тогда получается, в какой-то момент надо вообще все пулы уничтожать. И в этом же кадре снова создавать пулы под текущие нужды. Что-то мне не нравится в этой схеме. Удалять все, чтобы потом создать обратно необходимое. Если устраивать проверку, какие объекты сейчас на сцене используются и не удалять пулы, к которым они принадлежат, это может занять очень много ресурсов.

Это первый вопрос. Второй вопрос такой:

Если в пуле 500 объектов, надо их удаление размазать на продолжительно время. Удалять по 10 объектов за кадр?

А если 500 пулов, в каждом по 500 объектов? Может тогда тупо каждые 10 секунд из всех пулов удалять по 1 объекту? Или еще лучше: каждую секунду удалять 1 объект из 1 пула.

Так что тут два вопроса: что делать с опустевшими пулами и как размазать очистку пулов по кадрам.
Последний раз редактировалось Инженер 15 апр 2020, 15:57, всего редактировалось 1 раз.
Инженер
UNIт
 
Сообщения: 88
Зарегистрирован: 22 май 2016, 11:13

Re: Как подстраивать размер пула под текущие нужды?

Сообщение 1max1 15 апр 2020, 15:56

Не знаю, является ли Destroy тяжелым методом, но я думаю 500 объектов в 1 фрейме удалить не долго, могу ошибаться, конечно.
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

Re: Как подстраивать размер пула под текущие нужды?

Сообщение Инженер 15 апр 2020, 17:51

1max1 писал(а):Не знаю, является ли Destroy тяжелым методом, но я думаю 500 объектов в 1 фрейме удалить не долго, могу ошибаться, конечно.


Я думаю, Destroy будет довольно тяжелой операцией. Ок. Как размазать по нескольким кадрам очистку пулов, мы придумали. Больше всего мне нравится идея каждый кадр или секунду удалять 1 объект из 1 пула. Конкретную реализацию нужно тестить на конкретной сцене, т.е. можно делать это не каждый кадр, а реже; удалять больше объектов за раз; удалять не из одного пула, а сразу из всех и т.д. Пулы будут очищаться постепенно и очень дешево.

А что на счет удаления пустых пулов, которые уже были очищены?

Пока писал вопрос, пришла идея- мы же проходимся циклом по всем пулам, чтобы очистить каждый от лишних объектов. Можно дополнительно выполнять действие, что если количество объектов в пуле == 0, то уничтожаем пул целиком. Проблема в том, что за время создания кадра, этот пул мог использоваться, а мы этого не заметим. Туда пришло 5 объектов, потом ушло 5 объектов, в итоге пул использовался, а мы его удалим.

Пока писал предыдущее озарение, появилась мысль еще круче. Можно сделать класс и поместить его в Dictionary вместо LinkedList. Каждый такой класс будет содержать этот LinkedList с объектами пула, но главное, он будет хранить метку о том, как давно что-то бралось оттуда. Если этот пул постоянно используется, то надо оставить немножко лишних объектов в пуле на всякий случай. Если эти лишние объекты долго не востребованы, удаляем их. Если пул вообще давно не используется, постепенно удаляем все объекты по одному, пока не останется 0 и тогда уничтожаем этот пул.

Кому-то показалась моя идея хорошей или излишней? Может чего добавить? Ваши ответы толкают меня на глубокие размышления.
Инженер
UNIт
 
Сообщения: 88
Зарегистрирован: 22 май 2016, 11:13

Re: Как подстраивать размер пула под текущие нужды?

Сообщение Tolking 15 апр 2020, 19:32

Tolking писал(а):Но я, думаю, системы такой у тебя нет. Иначе бы вопрос был - "мне надо инстансить сотни объектов каждый кадр, а это прям фризы, а не падение фпс. Как?". И если бы ты дошёл до пула объектов, который все советуют, в этом случае, то понял что пул хорошо работает с одинаковыми объектами, а когда объекты разные получается, что в памяти нужно держать все... И все равно, если объекты сложные, с коллайдерами (особенно мешколлайдерами) будут ощутимые лаги...

Инстансить сотни объектов за кадр - это ECS... Либо по-старинке размазывать процесс по кадрам...

Во многих играх видно как погружается уровень при движении не из-за того, что создатели тупые...


Добавлю себя. Если размазывать процесс по кадрам. Не нужны пулы...
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2715
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Как подстраивать размер пула под текущие нужды?

Сообщение Инженер 28 апр 2020, 17:23

Не, это полный бред. То, что инстанцировано, должно на всегда оставаться на сцене и переиспользоваться много раз. Нет смысла очищать пул, потому что в итоге получим расширяющуюся кучу при создании новых объектов. Уж лучше пусть лишние объекты болтаются в пуле, меньше памяти потратим. Выяснил я это в этой теме: http://unity3d.ru/distribution/viewtopic.php?f=5&t=52467&p=316456#p316456

Вот что делать, если 1000 объектов в игре, у нас открытый мир, разные биомы, в которых используются разные наборы объектов с разными моделями, текстурами и т.д. Когда игрок находится в одном биоме (и использует 1 набор моделей этого биома), из пула (и со сцены) можно удалить не нужные пока остальные модели из других биомов. Ведь они все равно не нужны для текущего биома. Но игрок может вернуться обратно в прежние биомы, в которых побывал, и нам придется снова загрузить эти объекты. А объекты того биома, из которого он только что ушел, снова уничтожаем. И так по кругу. А куча в памяти все расширяется, расширяется, пока не настанет Out Of Memory.

В голову приходит разве что использовать Addressable Assets, надо будет тесты провести. Как там дела на счет расширения кучи, не известно. Мануал минималистичный.
Инженер
UNIт
 
Сообщения: 88
Зарегистрирован: 22 май 2016, 11:13

Re: Как подстраивать размер пула под текущие нужды?

Сообщение Tolking 28 апр 2020, 17:55

Out Of Memory на компьютере наступит очень не скоро... Когда место под свап закончится... Куча не расширяется бесконечно. Выделенная, но освобожденная память используется повторно, если, конечно, не пытаться все данные держать в памяти... Addressable Assets - это способ получить ассет - аналог ресурсы.лоад+бандлы. Они никак не связаны с хранением данных о мире и его структурой и инстансированием эти аспекты остаются прежними.
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2715
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4