Why is the Update phase more expensive than the Evaluate phase in the animation worker thread?
My understanding is that Update mainly reads and updates state data, whereas Evaluate performs complex skeletal calculations. Shouldn’t Update therefore be significantly less expensive than Evaluate?
Hi, the answer to this will depend very much on the structure of your graph. But generally, I would agree with you that in most cases, my expectation is that the evaluation phase is more expensive than the update. I’d need to take a look at an insights capture to give you more specific information, if you were able to share one?
For example, here’s a capture from GASP (taken in the editor):
In this, the majority of the update time is spent in BlueprintThreadSafeUpdateAnimation. The actual cost of updating the nodes within the anim graph (under ProxyUpdateAnimation) is relatively very small.
Are you running the anim bp in the experimental state machine + motion matching mode (ie. LocomotionSetup == 1)? If that’s the case, the state machine is adding overhead to just select an animation and a playback position. So you could remove the state machine entirely from the anim bp and add C++ logic to replicate what the SetBlendStackAnimFromChooser function does, along with any other anim node functions on states. After that, further profiling in another system that will show individual function call costs - like Superluminal - to see exactly what the hot paths are and then iterate based on that information.
I simply used the release version of UE 5.7 to create a GameAnimationSample project. After capturing a trace, I still found that Update costs more than Evaluate.
Thanks for attaching the screenshot. The figures that you see there for the update aren’t that different to those in the trace I attached a screenshot of. But the main difference is the evaluation time in your trace; there are only a few nodes being evaluated, so the evaluation cost is small. So when the evaluation time is short, update costs will be more obvious.
Another way to think of this is that the cost of updating a node doesn’t necessarily relate to its evaluation cost. So when you have many nodes being updated and evaluated, evaluation is likely to be more expensive. But when there are only a few nodes being evaluated, a single expensive update (like with the state machine update or the blend stack update) will skew the figures. If you look at FAnimNode_BlendStack::UpdateAssetPlayer and FAnimNode_StateMachine::Update_AnyThread, you’ll see those functions are reasonably complex. Whereas for evaluation, both of those nodes effectively do a little work and then just recurse down to their parent assets/nodes (assuming no transitions, blends, etc).
Was this causing you particular issues from a performance viewpoint, or were you generally interested in the differences?
I’d just like to know how to optimize these Update terms, as they have become the largest source of overhead on the animation worker thread in our project——even more expensive than Evaluate. Could you offer any suggestions?