Question about sync points

I have a few questions regarding the sync points created by the unity Job system along side the ECS:

  • In the docs for SystemBase it’s said:

. So let’s assume we have system A that writes and reads component S and we have system B that also writes and reads component S. So there seem to be a circular dependency here, who is executing first as it seems both are dependent on each other according to the docs?

  • It is also said in the same section that

. Does that mean that a sync point is created for each system dispatching a Job via

and the main thread is blocking for the the prior job to complete in-order for subsequent runs of the system to remain in sequence?

  • Is there some sort of sync mechanism frame wise? Let’s assume we have BulletSystem responsible for calculating new positions of bullets in the world. Let’s assume it’s taking huge times to calculate. Meanwhile other systems are probably finished and a new frame is being constructed and all the system run again, so we might see a behavior where everything is acting normal but the bullets are stuck midair doing calculations. Unless there’s some sync point frame wise and unity is somehow waiting for all dispatched job of the last frame to complete before moving to the next frame?

Some things to clarify:
A) A JobHandle, or Dependency, by itself, is not a sync point. Synchronization only happens when Complete() is called on the main thread. When you pass a JobHandle to a job, it delays the job from running until the previous JobHandle is completed on the worker threads. The main thread remains uninterrupted. This is often called “job-chaining”.
B) System order is the order you specify, or the order you let Unity guess for you if you use attribute-based system ordering. The Dependency property is computed right before OnUpdate by looking at the state of the system. That means that if you were to manually tick all systems using their Update() methods, changing the order of the systems every time, automatic dependency management would still work.

  1. See (B)
  2. No. It just updates the JobHandle Dependency contains so that future jobs using Dependnecy as their input dependencies don’t conflict with your just-scheduled job.
  3. Every system at the start completes the Dependency JobHandle it had from the last time it ran.

I got a few answers from what you wrote but I think you mixed some things up.
I think point A answers questions #2, the BeforeUpdate, updates Dependency with the previous JobHandle as far as I understand so to block the next Job of the system from completing by waiting on it on the worker thread of the next job.
About point B answering the dependency cycle chain, sorry I couldn’t understand from your words which system run before another? And I don’t specify any attributes just doing ForEach on both systems for the same component types?
And point #3 seems to just describe the mechanism behind Dependency and add to the answer of point #2 but doesn’t really answer my third question, which is what happen to a system taking too long in a scene? Sure subsequent runs of the system’s dispatched jobs won’t happen until previous jobs were completed as point A addresses, but there is not sync point on the main thread to wait on all the jobs per frame before continuing to the next frame? Because otherwise some systems could advance far beyond others, like the example I gave where let’s assume the bullet system is taking long, so everything is running fine but bullets gets almost stuck in the air and barely move, unless there’s a frame sync point, and you didn’t really address this question

Then by default, both systems will run in SimulationsSystemGroup and Unity will pick an order for you based on some magic logic I don’t fully understand. I override that mechanism in my own projects because it is easier for me to reason about my logic if I explicitly list out the order I want systems to run.

Systems run on the main thread. They schedule jobs that run on the worker thread. If the system itself (the OnUpdate) takes too long, then the frame will take a long time to complete because no other main thread task (including the frame finish logic engine-side) will be able to run while a system is running. I addressed jobs for the most part. Yes, it is possible for jobs scheduled late into a frame to roll over into the next frame. It looks like this (from a stress test):
6389154--712179--upload_2020-10-6_11-33-49.png

I see so if jobs can roll to the next frame unless waited on ofcourse with Complete then there’s no a “frame sync point” waiting for all the scheduled job of previous frame automatically.

And about this dependency order, I wish to know this magic logic, so if someone knows please tell :slight_smile:

Context: System Update Order | Entities | 0.14.0-preview.19
Where in the code you will find the magic so you can read for yourself: {project folder}/Library/PackageCache/com.unity.entities{some version number}/Unity.Entities/ComponentSystemSorter.cs