Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

DynamicBuffer<ByteBuffer> vs SharedComponentData

Discussion in 'Entity Component System' started by Deleted User, Nov 1, 2018.

  1. Deleted User

    Deleted User

    Guest

    Good day.

    What would be faster. Coppying byte[] to DynamicBuffer and then inject it. Or assigning byte[] array itself to SharedComponentData and then inject it? Any thoughts of what would perform the best in high load scenario?




    1st approach

    Code (CSharp):
    1. public struct ByteBuffer : IBufferElementData
    2. {
    3.     public byte Value;
    4. }
    Code (CSharp):
    1. PostUpdateCommands.SetBuffer<ByteBuffer>().Reinterpret<byte>().CopyFrom(data);
    2nd

    Code (CSharp):
    1. [System.Serializable]
    2. public struct SharedByteData : ISharedComponentData
    3. {
    4.     public byte[] Value;
    5. }
    Code (CSharp):
    1. PostUpdateCommands.SetSharedComponent(new SharedByteData { Value  = data } );
    Thank you.
     
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    SCD is not for storing data for each entity, it is for grouping entities according to common features, it should rarely change :) remember this.
     
  3. Deleted User

    Deleted User

    Guest

    Yes, but It will be changed only when created, that's it. Basically both of approaches are just for ReadOnly.
    So the question, what would be faster?
     
  4. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    558
    1) how many entities will share the same data? each SCD is stored per chunk, so if your entities have their own data (beware that for manages arrays, it compares by reference) you will end up with many chunks (16kB) with one entity each, resulting in huge memory and cache misses
    2) how big is the data, and does the length vary much? buffers are stored inside the chunk up to a certain size (you can control that with an attribute on the buffer) then fall back to be basically NativeArray<>
     
    Deleted User likes this.
  5. Razmot

    Razmot

    Joined:
    Apr 27, 2013
    Posts:
    345
    You can not use SharedComponentData in jobs, so forget about it if you want something fast!
     
  6. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    You can use SharedComponentData in job, just not can use Burst Compiler. For Burst you can operate with SCD index and Chunk Iteration.
     
  7. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    Can you give an example of this?
     
  8. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Which example? Working with SCD in non Bursted job or using SCD indeces in Chunk Iteration?
     
  9. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    The second one, using SCD indeces in Chunk Iteration. :)
     
  10. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Vacummus likes this.
  11. Deleted User

    Deleted User

    Guest

    Hi there. The data is serialized data of network packet. I can make it fixed, lets say 1024 max. But I ended up with idea of deserializing in consumer thread and creating an entity and sets of component that need to be there. So I am removing unnecessary copying. The only question is, would it work, to call the creation of enity in another thread? Would it invalidate componentGroup?

    Thank you.
     
    Last edited by a moderator: Nov 2, 2018
  12. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    558
    you need to use a BarrierSystem's command buffer to create entities from a job.
    but then you can't use managed types (byte[]) and SCD anymore, so you are left with one choice...
     
  13. Deleted User

    Deleted User

    Guest

    I won't create an entity from a job. But from a thread https://github.com/dave-hillier/disruptor-unity3d
    So I don't need managed array anymore, because everything will be deserialized in networking thread and appropriate entity will be created with SetComponent call.
     
  14. Deleted User

    Deleted User

    Guest

    The question is, calling EnityManager.CreateEntity() outside of the game loop would work?
     
  15. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    SCD works fine inside job and you can use managed types inside job, you just can't Burst them.
    upload_2018-11-2_17-36-36.png

    Code (CSharp):
    1. public struct CreatingJob : IJobParallelFor
    2.     {
    3.         [ReadOnly] public SharedComponentDataArray<ManualWorldComponent> scdArray;
    4.         public EntityCommandBuffer.Concurrent ecb;
    5.         public void Execute(int index)
    6.         {
    7.             ecb.CreateEntity(index);
    8.             ecb.AddComponent(index, new Position());
    9.             ecb.AddComponent(index, new Rotation());
    10.             ecb.AddSharedComponent(index, new ManualWorldComponent()
    11.             {
    12.                 array = new byte[10]
    13.             });
    14.             if (scdArray.Length > 0)
    15.             {
    16.                 Debug.Log(scdArray[0].array.Length);
    17.             }
    18.         }
    19.     }
    20.  
    21.     protected override void OnUpdate()
    22.     {
    23.        
    24.         new CreatingJob()
    25.         {
    26.             scdArray = _manualWorldGroup.GetSharedComponentDataArray<ManualWorldComponent>(),
    27.             ecb = PostUpdateCommands.ToConcurrent()
    28.         }.Schedule(5, 1).Complete();
    29.         Debug.Log("<color=green>Manager updated - </color> items in group " + _manualWorldGroup.CalculateLength());
    30.     }
     
    Last edited: Nov 2, 2018
    Deleted User likes this.
  16. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    558
    you still have the same limitations of jobs in managed threads, but they will not be enforced by the job safety system. therefore, while you *could* technically do it, know that "it is your foot and you are willingly pointing a gun at it" (and the fun fires randomly when you are not pulling the trigger)

    i'd still use command buffers (except you need to playback them manually on the main thread, because you cannot rely on a barrier system anymore)
     
  17. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Why can't this...
    Code (CSharp):
    1. ecb.CreateEntity(index);
    2. ecb.AddComponent(index, new Position());
    3. ecb.AddComponent(index, new Rotation());
    be made to work like this...

    Code (CSharp):
    1. ecb.CreateEntity(index, new Position(), new Rotation());
    Why is code that is supposed to be so performat looking so clunky and unoptimised?
     
    Last edited: Nov 2, 2018
  18. Deleted User

    Deleted User

    Guest

    Off topic
     
    Chiv likes this.
  19. Micz84

    Micz84

    Joined:
    Jul 21, 2012
    Posts:
    436