Deferring Subsystem Updates after Changes via DMU
<i>This post was originally made by <b>danij</b> on the dengDevs blog. It was posted under the category: Engine.</i>
When map data object properties are changed via DMU we currently go through the process of updating affected subsystems each time. Meaning that if the same properties are changed several times in succession this leads to a lot of wasted processing.
For example; I have been working on replacing the old system used for determining the divquad splits by only recalculating them when a change occurs that affects them (rather than the current method which recalculates every frame anyway). Even if I call this new method directly from DMU updates, it is not optimal.
What would be useful is to try to defer as much update work as possible to when it HAS to be done (or when we have time to spare). In the case of the above example, it is not necessary to recalculate the divquad splits until the next time the associated seg must be drawn.
Obviously, changes to the internal state of map objects will still need to be done immediately though.
Perhaps a "task-based" flag system could be used on map data objects? With the above example in mind; In DMU's Set_Property() we would set seg->updateFlags & UF_DIVHEIGHTS when necessary and then check that flag the next time the seg is drawn and then do the update work. In addition, if we have excess time during a tic we could iterate segs looking for those with this flag to do the update work.
Granted, this particular task is not very costly but it exemplifies my suggestion.
When map data object properties are changed via DMU we currently go through the process of updating affected subsystems each time. Meaning that if the same properties are changed several times in succession this leads to a lot of wasted processing.
For example; I have been working on replacing the old system used for determining the divquad splits by only recalculating them when a change occurs that affects them (rather than the current method which recalculates every frame anyway). Even if I call this new method directly from DMU updates, it is not optimal.
What would be useful is to try to defer as much update work as possible to when it HAS to be done (or when we have time to spare). In the case of the above example, it is not necessary to recalculate the divquad splits until the next time the associated seg must be drawn.
Obviously, changes to the internal state of map objects will still need to be done immediately though.
Perhaps a "task-based" flag system could be used on map data objects? With the above example in mind; In DMU's Set_Property() we would set seg->updateFlags & UF_DIVHEIGHTS when necessary and then check that flag the next time the seg is drawn and then do the update work. In addition, if we have excess time during a tic we could iterate segs looking for those with this flag to do the update work.
Granted, this particular task is not very costly but it exemplifies my suggestion.
Comments
DMU has far worse performance issues, as I recall, than the cost of updates to affected subsystems. This is definitely a topic for future development, but I hardly see it very important at the present time.
My intention was simply to begin a thread to open discussion on possible strategies in a topic which we will inevitably have to cover at some point.
Once that demo playback is fixed, I can set up automated profiling systems on a variety of hardware. An interesting note about pre-mature optimisation - changing the compiler build flags changes the timing dramatically ...