I thought that the jobs are all going to complete at the sync points. But it seems that when there’s no structural change, they can even run into the next frame.
Large computation jobs are default “multi framed”. They keep chugging along and wont interact with the main thread other than providing the bool .IsCompleted.
To create a sync point between the job and the main unity thread, use .Complete(). It’ll halt the main Unity thread from starting a new frame until the job is completed. From experiments, other scripts’ JobSystems/Update() will continue running until they hit the end of their functions but wait for the job that was called Complete() on before starting a new frame.
As for the two questions, I’ll have to let someone more experienced than me in using ECBS answer that.
Finding the answers to all these questions is mainly a long series of trial and error. Documentation is a good starting point but it’s incredibly barebones and lacks the minute detail needed to actually code something. See what works, what doesnt, and hope Unity doesnt deprecate the process when you finish implementing it (RIP [Inject]).
It really comes down to the dependencies. If you are not accessing Unity.Entities data then dependency management is completely up to you and by default a job that is not completed will run for however long it takes. There is no frame concept with jobs itself.
The Unity.Entities dependency management automatically completes all jobs that are return by JobComponentSystem’s when performing structural changes. And automatically creates dependencies based on read / write access.
Additionally the system will complete the job of the previous frame before running this frame.
If you have additional data structures that are shared by the system, like a hashmap or something like that. You need to add the dependencies of who is writing to it yourself.
Is it because the JobHandle returned by JobComponentSystem.OnUpdate() ?
If a job’s handle is NOT returned by OnUpdate, does that mean it will not be completed by the sync points and can run until the next time its system gets updated?
What if the system only updates once for 60 frames? Does that mean the max life time of the job is extended to 60 frames?
Is it right that the job schedule/complete sequences are only decided by JobHandles?
And the NativeContainers read/write relations have no effect on job schedule/complete sequence, they only raise safety warnings/errors in editor?
Yes. Jobs itself dont know what frames are. Frames are a main thread concept, that is enforced onto jobs by calling .Complete()
Naturally such a job can’t access component data directly. You have to copy it out first. The safety system tells you if your job has access to data that it shouldn’t if you don’t return the job handle.
Yes thats right. The native containers dont determine when something is completed. IN the editor the safety system simply validates that the dependencies you use at runtime match the read / write access of the containers to ensure a deterministic & race condition free code.
Since the buffers dont affect scheduling & dependencies, simply inform when there is incorrect setup. All the checks can be stripped out at runtime. Giving you the maximum performance in the deployed game, while having perfect race condition checks in the editor.
I have not tested this in a while, whilst I was able to run an ijob over several frames without main thread stall, I believe if you run a parallel job that utilizes all threads, the frame stalls.