Search Unity

Defragmenting chunks

Discussion in 'Entity Component System' started by 5argon, Nov 28, 2018.

  1. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    After I learned how to read the chunk debugger I see that I have got several chunks that are not full, like this one

    Screenshot 2018-11-28 12.34.02.png

    From my understanding when an entity in the middle of any chunk is going away it replaces with element at the end of that chunk without touching any other chunks. When an entity would be added, it would search for a chunk that is not full for space.

    Then "fragmented" chunks can be full again with enough new member added, but in my game after a certain initialization routine (combinations of messy create - add - set) there is no chunk movement ever again. Making it remains fragmented for the rest of the scene.

    Would it be a good idea if I can run some method which defrag chunks into all full chunks + one last chunk that is not full? That would make chunk iteration able to iterate contiguous memory longer before having to go to the next. Or does such a method exist today?

    (But in some case I am glad that the chunks are fragmented just so that IJobChunk can spread out the work by 1 chunk per thread, where if defragmented I would have got less parallelism.)
     
    JesOb and SubPixelPerfect like this.
  2. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    I think this is not a big deal in your case - this is only a little amount of waisted memory

    you can detect bad chunks by comparing chunk archetype capacity with entityes count in it. And if archetype contain lots of halfempty chunks. You can start moving data. Not sure what is the best way to move data, the only way I see is to change archetype for entityes one by one by adding/removing some tag component
     
    Last edited: Nov 28, 2018
  3. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    There is nothing you can do about it right now, but fragmentation & tiny / mega chunk support is definately something we will look at in the coming months.
     
    recursive, 5argon, FROS7 and 2 others like this.
  4. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    defragment.gif

    I've marked fragmeted data with Defragment tag-component
    and then removed it on few entityes per chunk per farme untill all removed

    Code (CSharp):
    1. public class DefragmentChunks : JobComponentSystem{
    2.   [Inject] EndFrameBarrier _barrier;  
    3.   private ComponentGroup _query;
    4.   protected override void OnCreateManager(){
    5.     _query = GetComponentGroup(ComponentType.Create<Defragment>());
    6.   }
    7.   protected override JobHandle OnUpdate( JobHandle deps )=>new Job(){
    8.     CommandBuffer = _barrier.CreateCommandBuffer().ToConcurrent(),
    9.     entityType = GetArchetypeChunkEntityType()
    10.   }.Schedule( _query, deps );
    11.  
    12.   private struct Job : IJobChunk{
    13.     public EntityCommandBuffer.Concurrent CommandBuffer;
    14.     [ReadOnly] public ArchetypeChunkEntityType entityType;
    15.     public void Execute( ArchetypeChunk chunk, int chunkIndex ){
    16.       var entities  = chunk.GetNativeArray(entityType);
    17.       for( int i = 0; i < math.min(50, entities.Length); i++ ){
    18.         CommandBuffer.RemoveComponent<Defragment>( i, entities[i] );
    19.       }
    20.     }
    21.   }
    22. }
     
    Antypodish, e199 and 5argon like this.
  5. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    noticed that chunks act really smart when you adding/removing component
    if you do same change to the less than half of the chunk - changed entityes are moved to another chunk
    but if change is made to more than half of chunk - archetype of the chunk changes and unchanged entityes are moved

    so in case of defragment if you need to force moving entityes to different chunk, to do it faster you have to change a bit less etities than half of chunk capacity
    math.min(chunk.Archetype.ChunkCapacity/2 -1, entities.Length)
     
    recursive, eizenhorn, 5argon and 2 others like this.
  6. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    I had made this assumption with a certain part of my design without any evidence that this would be the case, so it's really good to to get a confirmation that this actually happens.