Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Confusion about what kinds of data I can use in IJobEntity when using ScheduleParallel

Discussion in 'Entity Component System' started by unity_9GTK35cY9R08zQ, Mar 1, 2023.

  1. unity_9GTK35cY9R08zQ

    unity_9GTK35cY9R08zQ

    Joined:
    Sep 9, 2020
    Posts:
    10
    My understanding originally was that when scheduling multithreaded jobs you could only use blittable data types, and data structures couldn't just be shared between entities without making them readonly or as a parallel writer. however I recently realized I was accidently using some static variables from my ISystem class, and it was just working. what exactly am I not understanding here?

    here is an example of working code to demonstrate what I am talking about

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using Unity.Burst;
    4. using Unity.Entities;
    5. using Unity.Jobs;
    6. using Unity.Transforms;
    7.  
    8. public partial struct DotsOdditiyDemonstration : ISystem
    9. {
    10.     static string[] entitiesLocations;
    11.     static int nextIndex;
    12.     static EntityQueryDesc entitiesWithTransformDesc;
    13.     public void OnCreate(ref SystemState state)
    14.     {
    15.     }
    16.  
    17.     public void OnDestroy(ref SystemState state)
    18.     {
    19.        
    20.     }
    21.  
    22.     public void OnUpdate(ref SystemState state)
    23.     {
    24.         if (UnityEngine.Input.GetKeyDown("p"))
    25.         {
    26.             entitiesWithTransformDesc = new EntityQueryDesc()
    27.             {
    28.                 All = new ComponentType[] { ComponentType.ReadOnly<LocalTransform>() }
    29.             };
    30.  
    31.             EntityQuery entitiesWithTransformQuery = state.EntityManager.CreateEntityQuery(entitiesWithTransformDesc);
    32.  
    33.             entitiesLocations = new string[entitiesWithTransformQuery.CalculateEntityCount()];
    34.             nextIndex = 0;
    35.  
    36.             JobHandle EntityLocationOutputHandle = new EntityLocationOutputJob()
    37.             {
    38.             }.ScheduleParallel(entitiesWithTransformQuery, state.Dependency);
    39.  
    40.             EntityLocationOutputHandle.Complete();
    41.  
    42.             foreach (string s in entitiesLocations)
    43.             {
    44.                 UnityEngine.Debug.Log(s);
    45.             }
    46.         }
    47.     }
    48.  
    49.     public partial struct EntityLocationOutputJob : IJobEntity
    50.     {
    51.         public void Execute(Entity entity, in LocalTransform localTransform)
    52.         {
    53.             entitiesLocations[nextIndex] = $"Entity {entity} is at {localTransform.Position}";
    54.             nextIndex++;
    55.         }
    56.     }
    57. }
    upload_2023-3-1_12-54-58.png
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,753
    You aren't burst compiling your job. Statics that aren't readonly are disallowed in burst jobs but work fine in normal ones.

    What you're doing is not thread safe though.
     
    unity_9GTK35cY9R08zQ likes this.
  3. unity_9GTK35cY9R08zQ

    unity_9GTK35cY9R08zQ

    Joined:
    Sep 9, 2020
    Posts:
    10
    I was under the impression that the compiler wouldn't let me do anything that isn't thread safe. So to be clear, I have to manually make sure that I make it thread safe?
     
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,753
    If you use native containers then unity will provide safety. There is no safety in managed land.
     
  5. unity_9GTK35cY9R08zQ

    unity_9GTK35cY9R08zQ

    Joined:
    Sep 9, 2020
    Posts:
    10
    Ok, so what I first noticed was that I was reading from a static persistent native array. If I understand you right, that would be fine until I want to burst? Basically, can I use this for debugging and remove it later?

    Thank you very much for helping clear things up.
     
  6. suity447

    suity447

    Joined:
    Oct 18, 2022
    Posts:
    33
    If you were only reading from a shared array that would be fine. However nextIndex++ does also write to a static int. So multiple threads could read/write the same field at the same time.
     
  7. Laicasaane

    Laicasaane

    Joined:
    Apr 15, 2015
    Posts:
    358
    My advice is you should reason things in ECS without involving statics. That means: remove statics from your ECS code. That would give back to you something better.