Один фрагмент может содержать несколько команд. Наиболее эффективным (с точки зрения производительности) является выделение достаточно большого фрагмента, чтобы он не расширялся, когда вы продолжаете добавлять команды, прежде чем он сможет воспроизводиться. Вы сэкономите эту стоимость расширения памяти.
В вашем ECB вы можете установить MinimumChunkSize
, который по умолчанию составляет 4 * 1024 байта (предварительная версия 21).
Такие команды, как создание, уничтожение и создание экземпляра, имеют фиксированный размер. Но команда переменного размера — это команда с полезной нагрузкой, такой как Add или Set, в этом случае команда должна содержать то, что вы хотите установить из потоков обратно в основной поток.
Давайте посмотрим на размер каждой команды
EntityArchetype
: должен быть 1 указатель = 4
BasicCommand
: 4 * 3 = 12
Entity
: 4 + 4 = 8, так как он содержит индекс и версию
Тогда у нас есть
- Создать команды: 12 + 4 + 4 = 20
Этой команде ничего не нужно! - Команды сущностей: 12 + 8 + 4 = 24
Это, например, создание экземпляра и уничтожение, для работы ему нужна сущность. - Команды с типом: 24 + 4 + 4 = 32
Для команды «Удалить компонент» вы сохраняете полезную нагрузку, так что всего 32. - Команды с полезной нагрузкой: 32 + ???
Добавить или установить, в любом случае вам придется заплатить за размер вашей структуры. Вы не можете сделать «пустое добавление» (превью 21) - Команды буфера: 24 + 4 + 4 + (4 * 3) для заголовка буфера = 44
- Общие команды: 24 + 4 + 4 + 4 + 4 = 40
Таким образом, вы можете подумать только об этом: превысит ли он 4096, прежде чем он сможет воспроизводить? Если это так, увеличьте минимальный размер блока.
Также можно уменьшить минимальный размер чанка для оптимизации памяти, но я думаю такой маленький объем памяти того не стоит. Вы можете добавить больше команд в будущем и забыть увеличить размер фрагмента, и это повлияет на производительность. (Кроме того, если он слишком мал для размещения даже 1 команды, будет выделен фрагмент, равный размеру этой команды, чтобы избежать жесткого сбоя.)
Вот приблизительные цифры
Просто создай или уничтожь: около 170 команд.
Команды добавления/установки с полезной нагрузкой: типичный размер IComponentData
может составлять в среднем около 5 целых чисел? В этом случае у вас есть около 80 команд.
Таким образом, вы можете думать так: «Это задание должно создать около 500 объектов, поэтому размер должен быть около 4096 * 3».
Или просто рассчитайте его исходя из потребностей вашей работы:
4096 / (32 * sizeof(YourThing
))
Или кэшируйте рассчитанный размер фрагмента с помощью простого метода, например:
private const int noPayloadSize = 24; private const int withPayloadSize = 32; private const int multipleOf = 1024; public static int CalculateMinimumChunkSize(int createInstantiateDestroy, int remove, params (int sizeOf, int count)[] addSet) { var exactSize = (createInstantiateDestroy * noPayloadSize) + (remove * withPayloadSize) + addSet.Sum(x => (withPayloadSize + x.sizeOf) * x.count); return (int)(math.ceil(exactSize / (float)multipleOf) * multipleOf); }
В настоящее время вы должны смотреть на свой код, чтобы оценить количество команд на барьерах. Я надеюсь, что в будущем Entity Debugger сможет отображать некоторую полезную информацию на барьере.
пс. Для добавления SharedComponentData с помощью ECB кажется, что не заботится о размере вашей полезной нагрузки, поскольку он упаковывает этот объект и просто делает его указателем и хэшем.