Search Unity

Resolved Entity Command Buffer smart playback?

Discussion in 'DOTS Dev Blitz Day 2022 - Q&A' started by Rupture13, Dec 8, 2022.

  1. Rupture13

    Rupture13

    Joined:
    Apr 12, 2016
    Posts:
    131
    When I wish to perform a command buffer operation (AddComponent, RemoveComponent, DestroyEntity) on every entity in a chunk, is there some optimisation as to how these get processed?

    For example, say I want to add component B (via command buffer) to every entity in a chunk (or even archetype) of entities that currently only have component A. When the command buffer plays back the commands, does it recognise that the entire chunk can become the archetype AB, or does it move every entity from the A archetype to the B archetype individually?

    If such optimisations exist, are they different for the way in which you call the commands? (E.g.
    ECB.AddComponent<T>(entity)
    vs
    ECB.AddComponent<T>(NativeArray<Entities>)
    vs
    ECB.AddComponentForEntityQuery<T>(query)
    )
     
  2. cort_of_unity

    cort_of_unity

    Unity Technologies

    Joined:
    Aug 15, 2018
    Posts:
    98
    The unsatisfying answer is "it depends". For all EntityManager and EntityCommandBuffer methods that take a NativeArray<Entity>, in many cases we take a pass over the input entities and look for contiguous ranges of entities which we can process more efficiently as a batch. In the best case (where the array of entities contains full chunks worth of entities in order), the command can be processed comparably to the fast per-chunk codepath. In the worst case, however (either because the input array is out of order, or because the command in question doesn't support batching under the hood), we have no choice but to effectively foreach(var e in entities) { Command(e); }, and that's a huge cliff.

    So, generally speaking, you should try to pass as much pre-sorted Entity data as possible into these methods vs. calling them on individual entities. In theory this means the most efficient codepath would be the one where you pass an EntityQuery! But in practice, as you pointed out in this other thread, ECB EntityQuery commands currently degenerate to NativeArray<Entity> commands at playback, which I agree is a nasty surprise. We can discuss that further in the other thread.
     
    Rupture13 likes this.