Search Unity

NativeMultiHashMap Concurrent Performance

Discussion in 'Entity Component System' started by felipin, Nov 13, 2019.

  1. felipin

    felipin

    Joined:
    Nov 18, 2015
    Posts:
    49
    I'd been using NativeMultiHashMap to gather together spell occurrences according by target entity, but I noticed that NativeMultiHashMap.ParallelWriter uses atomic operations, are atomic operations too bad in this case(assuming that it'll be dozens of this systems running, one per each spell component) ? if it does, is there a better way to do it?


    Code (CSharp):
    1.  
    2.    [BurstCompile]
    3.    [ExcludeComponent(typeof(SpellHeader))]
    4.    public struct GatherBreakingSpellJob : IJobForEachWithEntity<SpellState<TSpell, TTargetComponent>>
    5.    {
    6.       [WriteOnly]
    7.       public NativeMultiHashMap<Entity, SpellEntry>.ParallelWriter SpellEntries;
    8.  
    9.       public void Execute(Entity Entity, int Index, ref SpellState<TSpell, TTargetComponent> SpellState)
    10.       {
    11.          SpellEntries.Add(SpellState.TargetEntity, new SpellEntry
    12.          {
    13.             Entity = Entity,
    14.             Spell = SpellState.Spell,
    15.             IsCasting = false
    16.          });
    17.       }
    18.    }
    19.  
    20.    [BurstCompile]
    21.    public struct GatherCastingSpellJob : IJobForEachWithEntity<SpellHeader, TSpell>
    22.    {
    23.       [WriteOnly]
    24.       public NativeMultiHashMap<Entity, SpellEntry>.ParallelWriter SpellEntries;
    25.  
    26.       public void Execute(Entity Entity, int Index, [ReadOnly] ref SpellHeader SpellHeader, [ReadOnly] ref TSpell SpellComponent)
    27.       {
    28.          SpellEntries.Add(SpellHeader.TargetEntity, new SpellEntry
    29.          {
    30.             Entity = Entity,
    31.             Spell = SpellComponent,
    32.             IsCasting = true
    33.          });
    34.       }
    35.    }
    36.  
    37.    [BurstCompile]
    38.    public struct SpellJob : IJobNativeMultiHashMapVisitKeyValue<Entity, SpellEntry>
    39.    {
    40.       [NativeDisableParallelForRestriction]
    41.       public ComponentDataFromEntity<TTargetComponent> TargetComponentDataFromEntity;
    42.  
    43.       [WriteOnly]
    44.       public EntityCommandBuffer.Concurrent EntityCommandBuffer;
    45.  
    46.       [NativeSetThreadIndex]
    47.       int m_ThreadIndex;
    48.  
    49.       public void ExecuteNext(Entity TargetEntity, SpellEntry SpellEntry)
    50.       {
    51.          bool IsCasting = SpellEntry.IsCasting;
    52.  
    53.          if (!TargetComponentDataFromEntity.Exists(TargetEntity))
    54.          {
    55.             EntityCommandBuffer.DestroyEntity(m_ThreadIndex, SpellEntry.Entity);
    56.  
    57.             if (!IsCasting)
    58.             {
    59.                EntityCommandBuffer.RemoveComponent(m_ThreadIndex, SpellEntry.Entity, typeof(SpellState<TSpell, TTargetComponent>));
    60.             }
    61.  
    62.             return;
    63.          }
    64.  
    65.          var TargetComponent = TargetComponentDataFromEntity[TargetEntity];
    66.          ref var Spell = ref SpellEntry.Spell;
    67.  
    68.          if (IsCasting)
    69.          {
    70.             Spell.Cast(ref TargetComponent);
    71.  
    72.             EntityCommandBuffer.AddComponent(m_ThreadIndex, SpellEntry.Entity, new SpellState<TSpell, TTargetComponent>
    73.             {
    74.                Spell = Spell,
    75.                TargetEntity = TargetEntity
    76.             });
    77.          }
    78.          else
    79.          {
    80.             Spell.Break(ref TargetComponent);
    81.  
    82.             EntityCommandBuffer.RemoveComponent(m_ThreadIndex, SpellEntry.Entity, typeof(SpellState<TSpell, TTargetComponent>));
    83.          }
    84.  
    85.          TargetComponentDataFromEntity[TargetEntity] = TargetComponent;
    86.       }
    87.    }
     
  2. Deleted User

    Deleted User

    Guest

    Switching to ScheduleSingle helped me with performance. No Concurrent writing needed.
     
    felipin likes this.
  3. felipin

    felipin

    Joined:
    Nov 18, 2015
    Posts:
    49
    this is my approach now, thxx :D
     
  4. Deleted User

    Deleted User

    Guest

    No problem, it just frees all the other worker threads of unnecessary workload :)
     
    felipin likes this.