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

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

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

CD
> значит в какой-то момент компонентов было гораздо больше чем сейчас
Была орда монстров, а игрок их всех быстро перестрелял и идет медленный спавн новых.

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

Куча ситуаций может быть.


#16
17:42, 21 авг. 2019

Robotex
> ведет к branch misprediction

ну так храни отдельно список активных и только их имей

#17
(Правка: 21:26) 21:25, 21 авг. 2019

Сделать связный список, но не через указатели/ссылки, а через индексы в пуле же.

UPD. Свободные элементы пула тоже в такой же связный спискок через индексы связать.

#18
21:26, 21 авг. 2019

KISS

#19
(Правка: 1:42) 1:40, 22 авг. 2019

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

#20
4:48, 22 авг. 2019

*Lain*

ему нужно на PS3/XBox360 - вот где место разгуляться

#21
8:58, 22 авг. 2019

Robotex
> потому что в памяти находятся не только данные, но и инструкции
А ты правильно понимаешь паттерн object pool? Причём тут инструкции, если речь про объекты? Для object pool вообще нет проблемы с обновлением ссылок, т.к. там нет перемещений.

#22
9:17, 22 авг. 2019

Мизраэль
> А ты правильно понимаешь паттерн object pool?
У меня комбинация из ObjectPool и DataLocality

innuendo
> так храни отдельно список активных
Джавист что ли? Миллион объектов,  бро

*Lain*
> зарелизь сначала игру
Игра уже есть. Это не коммерции ради, а для самообразования


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

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

Robotex
> Джавист что ли? Миллион объектов,  бро

ооооо.... жесть, std::vector<Object*> activeObejcts;

всё! скорее всего они не меняют состояние active каждый кадр/тик
это где у тебя миллион объектов?

#24
12:22, 22 авг. 2019

innuendo
> std::vector<Object*> activeObejcts

пихать в вектор будешь по одному объекту? Догадываешься, как они будут расположены в памяти? Кеш охереет ;)

#25
12:23, 22 авг. 2019

innuendo
> где у тебя миллион
миллион это к слову. Как синоним "до*уя"

Но в стратежках, например, может быть очень много юнитов на экране. Римская империя по 50 тыс. воинов собирала и больше

#26
12:26, 22 авг. 2019

Robotex

всё ... ты мне надоел ... это всё писькомизации

#27
12:26, 22 авг. 2019

innuendo
а, ты имел ввиду, что ссылки на объекты из пула пихать, а не создавать по одному объекту. Ну, вариант конечно.

Но сейчас у меня все активные объекты расположены рядышком друг с другом и по ним легко пробежаться в цикле (update-метод принадлежит пулу целиком). А вот твой вариант все равно будет приводить к cache miss при большом количестве объектов

#28
(Правка: 18:28) 13:30, 22 авг. 2019

Сделал так:

inline void exchangeObjects(int32_t object1, int32_t object2)
{
    std::swap(m_objects[object1], m_objects[object2]);
    std::swap(m_internalIndices[m_externalIndices[object1]],
                                m_internalIndices[m_externalIndices[object2]]);
    std::swap(m_externalIndices[object1], m_externalIndices[object2]);
}
#29
(Правка: 18:41) 18:39, 22 авг. 2019

Robotex
многочисленные элементы с произвольным временем жизни имеет смысл хранить по двум стратегиям:
1) объекты хранятся в одном массиве std::vector<T> objects; и при освобождении какого-то элемента он просто помечается как свободный и его индекс добавляется в пул свободных элементов. в таком подходе id объекта — это его номер в массиве, он постоянный при добавлении и удалении других элементов, недостаток подхода — неудобно пробегаться только по существующим элементам. для этого имеет смысл пересоздавать каждый кадр дополнительный массив с id активных элементов и пробегаться по нему, но это создаёт дополнительный уровень индирекции.

2) объекты хранятся в массиве std::vector<T> objects; при освобождении элемента он помечается как свободный, а каждый кадр делается проход с перегруппированием существующих элементов без пустых мест, но при этом у них меняются индексы и нужно поддерживать дополнительный массив, который по для каждого id объкта будет хранить, где он находится в массиве. этот подход позволяет быстро итерироваться по всем объектам по порядку, но медленнее (через индирекцию) позволяет обращаться к ним по уникальным id.

таким образом, первая стратегия даёт быстрый доступ по id, но медленный итератор. вторая стратегия даёт быстрый итератор, но медленный доступ по id. так как узкое место обычно в реализации самой системы, которая обрабатывает все объекты по порядку, то обычно дефолтной стратегией хранения выбирается вторая.

ещё обращу внимание, что обе стратегии разделяют время доступа на кадры — предполагается, что объекты при удалении помечаются как свободные, а все внутренние реструктуризации и переиндексации происходят только один раз перед началом/после конца кадра.

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