Войти
ПрограммированиеФорумОбщее

Обновление ссылок на компоненты в object pool при их перемещении в массиве

Страницы: 1 2 3 4 Следующая »
#0
13:00, 21 авг. 2019

Сорян за дурацкий вопрос, почему-то не могу быстро придумать решение.

Суть вот в чем. GameEntity это всего лишь контейнер для компонентов, которые представляют из себя целочисленный индекс в пуле компонентов этого типа.

И все было бы прекрасно, но при удалении объекта, я перемещаю его в пуле в конец, а затем уменьшаю счетчик объектов на единицу. Таким образом и память не фрагментируется, и кеш доволен.

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

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

В голову пришла мысль о том, чтобы отказаться от GameEntity вообще и использовать вместо него просто ID, по которому можно найти все компоненты конкретного Entity. Но ведь поиск будет занимать гораздо больше времени, чем O(1). Да и иметь единый объект, по которому можно получить все компоненты, тоже удобно, хотелось бы это сохранить.

Какие есть идеи как выйти из ситуации? Иметь в каждом компоненте указатель на его GameEntity и обновлять индексы при перемещении?


#1
(Правка: 14:18) 13:47, 21 авг. 2019

В принципе, можно иметь два ID: внешний и внутренний и мепить один в другой с помощью std::map.

Главное при этом, чтобы std::map тоже попал в кеш

#2
(Правка: 14:23) 14:22, 21 авг. 2019

указатели не нужны, можно ограничиться только индексами, которые суть скрытые указатели, но да, их надо обновлять
тут было
https://gamedev.ru/code/forum/?id=245643

> std::map тоже попал в кеш
ерунду не пиши

#3
15:03, 21 авг. 2019

да уж ... школьники думают про кэш

#4
15:09, 21 авг. 2019

innuendo
> школьники
Бро, мне 30 лет уже ;)

#5
15:12, 21 авг. 2019

#!
> ерунду не пиши
поясни

#!
> их надо обновлять
пока вижу так: при обмене элементов местами в массиве, меняю также их индексы в мапе внешних индексов.

Напрягает правда, что для получения компонента придется каждый раз дергать _physSystem->GetComponent(physComponentIndex);

Но видимо полностью отказаться от указателей и вызова внешних функций не выйдет.

#6
15:47, 21 авг. 2019

Robotex

юзай всегда ptr, id только в редких случаях

#7
16:19, 21 авг. 2019

Robotex
> И как же тогда быть?
https://www.gingerbill.org/article/2019/02/16/memory-allocation-strategies-004/

#8
16:34, 21 авг. 2019

innuendo
> юзай всегда ptr
ptr обновлять тяжело

#9
16:38, 21 авг. 2019

CD
> https://www.gingerbill.org/article/2019/02/16/memory-allocation-strategies-004/

Это шутка?

Изображение


Вот именно от таких приколов я и пытаюсь избавиться.

У меня статичный массив с заранее аллоцированными объектами, которые идут строго один за одним. Активные сдвигаются обменом элементов вверх, неактивные вниз.

Таким образом нет никаких аллокаций/деаллокаций в геймлупе и пробежать по массиву это cache-friendly операция

#10
16:41, 21 авг. 2019

Robotex
ты это ...сразу пиши на асме будет очень круто

#11
16:50, 21 авг. 2019

а зачем перемещать элементы по массиву при освобождении? просто пометь его как свободный и всё.

#12
17:03, 21 авг. 2019

Robotex
Если у тебя слишком много дырок в пуле, это значит в какой-то момент компонентов было гораздо больше чем сейчас.
И тогда что? Время кадра вылезло за бюджет? Тогда нужно это исправлять, и аллокатор никак этому не поможет.
Не вылезло? Значит с меньшим количеством компонентов тем более никаких проблем.

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

#13
17:11, 21 авг. 2019

Robotex
> > юзай всегда ptr
> ptr обновлять тяжело

а.... я забыл, что у тебя Крайзис 6.0

#14
17:25, 21 авг. 2019

Мизраэль
> просто пометь его как свободный и всё
потому что в памяти находятся не только данные, но и инструкции

и вот такая вот хрень

foreach(el in Elements)
{
  if(el.isActive())
  {
    
  }
}

ведет к branch misprediction


innuendo
> я забыл, что у тебя Крайзис 6.0
миллион физических объектов, взаимодействующих друг с другом

Страницы: 1 2 3 4 Следующая »
ПрограммированиеФорумОбщее