ServerWorld Update on separate thread

I’ve been going down a bit of a rabbit hole while trying to find some optimization opportunities on a ECS netcode project.

I’ve always just assumed that the ECS World Update has to be run on the main thread, but when I tested offloading parts of it turns out it technically kind of works. I thought scheduling would be the hard blocker, but that seems to superficially work, which was a bit surprising to me. Even if we could just run the world update with only using Run calls instead of Schedule that would be great.

I did set up an example project to better show what I mean: GitHub - maxha651/ServerWorldUpdateOnThread: Proof of concept of running ECS Netcode Server World on a non-main thread

There are definitely some problems, the biggest one that there is no Temp allocator when moving to a non-main thread. But this is close enough to working with fairly small changes that I wanted to check if a) anyone else has done something like this? and b) if supporting offloading at least parts of the World Update to another thread is something that is considered by Unity?

Performance gains that can be had here is pretty massive and avoids the problem with uneven frame times when the server has to update.

1 Like

They’ve already been looking into this internally.

My worry with that is that they are just looking at doing the parellelism on a system level when doing it on a world level is close to just working at this point and would be very beneficial for the netcode case.

Scheduling at world level does not work at all at the moment. You get it working for some case scenario but it is really not designed for that.

We are not just looking at system-level parallelism. World scheduling is also on the radar (as been for bit) but require other building blocks to get it working. There are strong assumptions in many places about main-thread execution that requires to be removed.
Nor to speak about job scheduling itself, not designed to be kick in from other threads.

Technically speaking, if we have system level parallelism, we also are getting closer to world parallelism, because worlds are just a collection of systems.
Where and how these systems (that can run in parallel) can be scheduled from is then the next necessary bit to be addressed (among others).

Stay tuned, the parallel world update is and has been considered as important feature.

2 Likes

Thanks, I appreciate you looking into this feature. If we could have the server world on a different thread in any form that would help a lot and make the combined server+client world that has been mentioned in this forum before less relevant (imo). Also for those projects that want to have a single dedicated server app running multiple server worlds this should help as well.

World scheduling is also on the radar (as been for bit) but require other building blocks to get it working.

Technically speaking, if we have system level parallelism, we also are getting closer to world parallelism, because worlds are just a collection of systems.

I agree with the first part here, but if system parallelism is one of those building blocks then that makes me worried that we are blocking this feature unnecessarily. For system parallelism you’ll have to solve e.g parallel dependency handling which just isn’t the case for a world which is updated on a single thread, right?.

There are strong assumptions in many places about main-thread execution that requires to be removed.
Nor to speak about job scheduling itself, not designed to be kick in from other threads.

Yeah I was surprised it let me fire off jobs from another thread at all, that made me a bit hopeful it was actually something intended :slight_smile:

The hard assumptions I could see was

  • Temp allocator not working.
  • Jobs, but apart from debugger there is no hard blocker currently (was hoping this could be worked around by running everything with Run in a single thread, sadly there is no way to switch off job threads for a single world…).
  • InitializationSystemGroup had some call to a main thread function, which I solved by just running that group from the main thread instead.

Are there others you know of? I’m only thinking about the basic case of a server world, of course if you call e.g. some rendering function from a system that won’t work.

1 Like