Hey,
I’m sure this question has been asked somewhere before since it seems to have been in the Engine since 4.0 at least and most likely before that as well.
We have several systems that make use of core tickers, e.g. FTSTicker::GetCoreTicker().AddTicker. When looking at profiles in Insights, we noticed that the updates to these systems were happening after the sync point between the game and render threads meaning that there could be an X number of idle ms before their update. When you look at the code, the sync point is very clearly before the core ticker update, with this comment above it “// This could be perhaps moved down to get greater parallelism”.
Questions
- Why not move the sync point after the core ticker update as shown in the attached image?
- What ticker should systems use if they want to be ticked before this sync point?
- Actors or TickableGameObjects are options but they come with some extra constraints that can be a bit frustrating to deal with (e.g. must be an actor), FTSTicker::GetCoreTicker().AddTicker is very useful because it can be used just about anywhere you want.
I made a few assumptions on why this hasn’t been done so wanted to share my thoughts on those up front as below.
- It’s too risky.
- Absolutely agreed that moving this unconditionally would be an unacceptable risk for existing projects upgrading but, couldn’t you guard it behind a feature flag to allow projects to decide which behaviour they want?
- There is no practical impact on the game thread and render thread performance since the core ticker work done after the sync point essentially becomes work done for the next frame.
- Absolutely agreed on that however, it would make a difference if systems in the core ticker update schedule async work to be started. Sometimes the game thread can be waiting 5 to 10ms for the render thread to finish depending on the game, this could easily be enough time for async work to be scheduled and potentially even completed in.
- Just move systems to use another ticker instead.
- While we can do this for systems we own, some of those other tickers come with constraints that make them harder to use (e.g. it must be an actor etc) and additionally, for Third Party plugins e.g. Wwise we’d have to modify their code to make it work which is also a risk and a maintainence burden for each plugin.
Overall, I am mainly just curious to hear the official answer and recommended direction on this, the most compelling reason to do this would be to support faster scheduling of async work, results would vary depending on each game but it could be a 5 to 10 ms faster completion of async work, I appreciate it is a very risky change though.
Insights Example
Red = Where all Core Ticker work is being currently done in the Engine by default, after the long game/render thread sync point.
Green = The time in which async work could be being executed from systems that trigger async work during the core ticker update.
[Image Removed]
Code Snippet
[Image Removed]
[Attachment Removed]