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

Multiple physics worlds for parallel prediction jobs?

Discussion in 'Physics for ECS' started by Bas-Smit, Mar 24, 2021.

  1. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    274
    For my project I need to predict trajectories for dynamic bodies. I have code to create physics worlds from entity queries and running the prediction entirely on worker threads is possible with a small modification to the physics package.

    The final piece of the puzzle is to create a parallel job. As I know my worlds will rarely change I want to reuse them. The problem is how to get one of these worlds to a thread for performing the actual work.

    Currently I create maxWorkerThreads + 1 worlds and schedule a IJobFor with same nr array length parameter (alternatively I could use NativeThreadIndex). I can not pass a NativeList<PhysicsWorld> to my job as Native structures can not be nested. I created my own List which is a NativeList but without the safety features. This allows me to pass the PhysicsWorlds in to the job and the job runs fine, however when I enable memory leak detection I get errors as it thinks I'm leaking local variables which are instead stored in a List of the type mentioned above.

    I am really at a loss here, I can hardcode a maximum number of physicsworlds with fields for each individually, but this is far from ideal, any way I can store a dynamic number of physicsworlds without tripping up any of the safety systems, or associate them with IComponentData somehow? I do not care if I lose the safetey systems for these worlds if it helps :)
     
  2. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    862
    Worlds are closely tied to ECS. Does each of your prediction runs really require separation? Cannot you just have one predictive world and step it using your inputs from multiple projectiles? Or would this cause odd interactions you don't want?
     
  3. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    274
    It's not about separation, I have multiple dynamic bodies per world set up not to interact with eachother through their filters, it's about running a parallel job

    I want to do _a lot_ of prediction, ideally at full precision (timestep)
     
    Last edited: Mar 24, 2021
  4. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    862
    This is what I do. You can predict everything you should separate out our graphics etc.

    Code (CSharp):
    1.     void Start()
    2.     {
    3.         locECSWorld = new World("lockStepWorld", WorldFlags.Simulation);
    4.         var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
    5.  
    6.         DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(locECSWorld, systems);
    7.  
    8.         FixedStepSimulationSystemGroup fixGroup = locECSWorld.GetExistingSystem<FixedStepSimulationSystemGroup>();
    9.         fixGroup.FixedRateManager = new FixedRateUtils.FixedRateSimpleManager(MyFixedTimeStep);
    10. }
    11.  
    12.     private void updateOnce(inputData myInputData)
    13.     {
    14.      //do input stuff here
    15.      locECSWorld.Update();
    16.      }
    17.  
    Just copy ECS data when you need to make a new world.
     
    Last edited: Mar 24, 2021
  5. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    274
    This is way too slow, it can only predict a single frame without going back to the main thread and incurs prohibitive overhead for scheduling. I'm looking to predict tens of single bodies tens to hundreds of frames which is feasible given the approach outlined above, all I need is a way to get multiple worlds to a parallel job
     
    Last edited: Mar 25, 2021
  6. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
  7. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    274
    thats the pool one right? Yeah that's where I started, I found that I had to modify the physics package to predict beyond one frame without going back to the main thread

    I am currently predicting 29 independent spheres 180 frames in 2 and a bit ms on a single thread, which is already pretty good imo

    If I store the worlds in fields on the system the memory leak detection does not get triggered and I can trigger a parallel job, I am seeing longer wall times though and an order of magnitude more total resources consumed, not sure what is causing this...
     
    Last edited: Mar 25, 2021
  8. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    862
    The ImmediateMode demo is not good for heavy prediction of everything but is fine for single player prediction of weapons trajectories I guess. Stepping a world from update and adding whatever systems and entities you want will just gives you total control.

    If you try doing complex stuff using the ImmediateMode demo as an example the complexity will just explode. I actually think the use cases for StepImmediate are extremely limited and you sound like you are beyond the limit.
     
    Last edited: Mar 25, 2021
  9. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Yeah StepImmediate is designed for lightweight simulations, nothing too heavy. But we did have asks for such stepping mechanism, for isolated small worlds, that's why we did it. It definitely improved performance a lot in this use case of pool prediction.
     
  10. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
    Hi @Bas-Smit , I don't think you can have native collections in native collections inside a Job. For further info about that and any potential workarounds, I'd suggest posting a thread on DOTS subforum.
    It sounds like you're quite familiar with physics-related stuff, like StepImmediate, so I thought it'd be useful to suggest contacting DOTS people, who should know all the details and might be able to suggest something.
     
    Bas-Smit likes this.
  11. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    274
    memory leak detection does not support nesting unfortunately, tertle suggested using proxys which is a viable approach but a bit too heavy handed for my purposes

    I ended up using a List with the safety features removed to allow for nesting, while storing each world in a field to satisfy the memory leak detection...

    If I ever figure out why the parallel job does not provide any gains I'll post the results here, I am pretty impressed by the results so far
     
    Last edited: Mar 27, 2021
  12. TCROC

    TCROC

    Joined:
    Aug 15, 2015
    Posts:
    230
    @Bas-Smit This may be overly simple for your use case, but if you or anyone else like me is in a situation where you wanted the additive scene equivalent of Unity's default Physics system, I did this on start in a MonoBehaviour:

     physicsSceneWorld = DefaultWorldInitialization.Initialize($"{gameObject.scene.handle}"); ;
     
    Last edited: Oct 16, 2021
    Bas-Smit likes this.