bevy
bevy copied to clipboard
Immediately poll the executor once before spawning it as a task
Objective
At the start of every schedule run, there's currently a guaranteed piece of overhead as the async executor spawns the MultithreadeExecutor task onto one of the ComputeTaskPool threads.
Solution
Poll the executor once to immediately schedule systems without waiting for the async executor, then spawn the task if and only if the executor does not immediately terminate.
On a similar note, having the executor task immediately start executing a system in the same async task might yield similar results over a broader set of cases. However, this might be more involved, and may need a solution like #8304.
Seeing decent gains on AssetEvents, UpdateAssets, and PreUpdate. All the other schedules were pretty neutral. I'm guessing this helps the most when there are a bunch of systems that are ready to run right away and hurts a little because the main thread is more likely to go to sleep, since the systems are more likely to get stolen and run on other threads.
AssetEvents
UpdateAssets
PreUpdate
Yep, this has the strongest impact on schedules with a large number of unblocked systems that have very little to do, which is surprisingly common. These little bits tend to add up, so it ends up being a death by a thousand cuts.
I think this is good proof that there's a lot we're leaving on the table when it comes to scheduling overhead, and an eventual solution like #8304 may be able to help.
I'd like to take this moment to ask:
Why are AssetEvents and UpdateAssets separate from PreUpdate anyway? Wouldn't it be better if they were part of PreUpdate and use system sets / ordering inside of PreUpdate?
I agree with that analysis: I didn't change it in the Stageless changes to avoid subtle bugs but it can and should be cleaned up.