Search Unity

Question NativeMultiHashMap Explanation wanted, please

Discussion in 'Entity Component System' started by SuperFranTV, Dec 22, 2021.

  1. SuperFranTV

    SuperFranTV

    Joined:
    Oct 18, 2015
    Posts:
    140
    Hello Guys,
    at the moment all my progress depends on one thing.
    I would like to add the parallel writer.
    Then get all values from one key into a NativeArray or something similar.

    I'am really new to Dots and need some help out.

    Please let me know if some of my practice are the wrong way.

    The Job:
    Code (CSharp):
    1.     [BurstCompile(FloatPrecision.Low, FloatMode.Fast)]
    2.     struct SetupJob : IJobFor {
    3.  
    4.         [WriteOnly]
    5.         public NativeMultiHashMap<int, int> data;
    6.  
    7.         public void Execute (int i) {
    8.             //Only for testing
    9.             //Adds a key if the key doesn't exists
    10.             //Adds the value if the key exist
    11.             data.Add(i, data.Count());
    12.         }
    13.     }

    How i call the Job:
    Code (CSharp):
    1.     [NoAlias]
    2.     NativeMultiHashMap<int, int> data;
    3.  
    4.     void OnEnable () {
    5.         //Why Allocator.Persistent? Because I'am using it later more often, so it should stay all time the Script is active.
    6.         data = new NativeMultiHashMap<int, int>(1, Allocator.Persistent);
    7.  
    8.         //Example
    9.         JobHandle job = new SetupJob { data = data }.ScheduleParallel(100000000, 64, default);
    10.         job.Complete();
    11.         //Don't know if JobHandle.ScheduleBatchedJobs() adds some performance or is better?
    12.  
    13.         //ScheduleParallel throws an error, i need to convert it to ParallelWriter?? but this make the most things strange for me
    14.     }
    15.  
    16.     //For Testing
    17.     bool once;
    18.  
    19.     void LateUpdate () {
    20.         if (!once) {
    21.             //Gets all Values from Key 0 but why is this also a NativeMultiHashMap? I need to convert it to a NativeArray in best practice
    22.             var output = data.GetValuesForKey(0);
    23.             once = true;
    24.         }
    25.     }
    26.  
    27.     void OnDisable () {
    28.         //Remove the NativeMultiHashMap if script disabled
    29.         data.Dispose();
    30.     }

    All i ask about is commented inside the code.

    But how can i use this NativeMultiHashMap as ParallelJob?
    I read about add .ParallelWriter to it but then i only got the .Add comment and can't get the values out of it?

    I'am very happy if someone can help me a bit out and shows me some code how to use ParallelWriter correct, this will also help many other people too i think.

    Thanks in advance.
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,779
    Please don't ping bunch of people, to grab the attention.
    They will reply, if they notice thread and feel to.
    You write to native hash maps using ParallelWriter, but read from tje, not using ParallelWriter.
     
  3. SuperFranTV

    SuperFranTV

    Joined:
    Oct 18, 2015
    Posts:
    140
    Okay i deleted the ping.
    But i dont find any documentation how to add ParallelWriter correct or use it? Can i simply cast a parallelwriter hasmap to a normal back??

    Edit: (i understand it so)
    The Job:
    Code (CSharp):
    1.     [BurstCompile(FloatPrecision.Low, FloatMode.Fast)]
    2.     struct SetupJob : IJobFor {
    3.  
    4.         [WriteOnly]
    5.         public NativeMultiHashMap<int, int>.ParallelWriter data;
    6.  
    7.         public void Execute (int i) {
    8.             data.Add(i, data.Count());
    9.         }
    10.     }

    How i call the Job:
    Code (CSharp):
    1.     [NoAlias]
    2.     NativeMultiHashMap<int, int>.ParallelWriter data;
    3.  
    4.     void OnEnable () {
    5.         data = new NativeMultiHashMap<int, int>(1, Allocator.Persistent).ParallelWriter;
    6.  
    7.         JobHandle job = new SetupJob { data = data }.ScheduleParallel(100000000, 64, default);
    8.         job.Complete();
    9.     }
    10.  
    11.     bool once;
    12.  
    13.     void LateUpdate () {
    14.         if (!once) {
    15.             //Error: GetValuesForKey doesn't exist for N.ParallelWriter
    16.             var output = data.GetValuesForKey(0);
    17.             once = true;
    18.         }
    19.     }
    20.  
    21.     void OnDisable () {
    22.         //Error, can't Dispose NativeMultiHashMap.ParallelWriter
    23.         data.Dispose();
    24.     }
     
    Last edited: Dec 22, 2021
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,779
    It is in similar manner as EntityCommandBuffer.ParallelWriter
    var hm = new NativeHashMap<T, T>(1000, Allocator.TempJob);
    var hmp = hm.AsParallelWriter();

    pass hmp to the job, where you write to it in parallel. (as per your first case).
    pass hm to the next job, where you read in parallel, after the job that was writing to it. (you got missing).
     
  5. SuperFranTV

    SuperFranTV

    Joined:
    Oct 18, 2015
    Posts:
    140
    Thank you, now I know how it is meant and understand how to use it.

    So far, I've only rarely looked at it ECS.
    Is it better performing than DOTS when generating many meshes or something like this?

    My other important question is, if i'am using NativeMultiHashMap.GetValuesForKey(i) it returns me a NativeMultiHashMap why? and is there a better way to get all values from a specific key into a NativeArray or something similar?

    Edit:

    I'am noticed that NativeMultiHashMap Capacity won't increase automatically if i do it in Parallel job right?
     
    Last edited: Dec 22, 2021
  6. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,779
    It will not. Is not like normal list or Dictionary, which can increase in capacity when writing to it.
    With Native collections, you need predefined enough capacity before hand.

    I think it should return Native Array. Unable to check atm.

    You are just writing values to it. So is as fast, as data size, you try to put into it.
    Mind, in contrast to Dictionary which uses references, nmhm can not use refs by default. You probably could do something with pointers however.