Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

PlayableGraph Evaluate performance/best practices

Discussion in 'Timeline' started by zander_m, Mar 5, 2019.

  1. zander_m

    zander_m

    Joined:
    Feb 7, 2019
    Posts:
    15
    I was hoping to get a bit more insight into the internals of playable graph evaluation to better understand the performance implications of different playable setups. A few questions:

    1. I've read calling Update manually on an Animator "means your animators will run single-threaded". How much of the cost of an Animator update comes from the graph evaluation? Is calling Evaluate on a playable graph with Animation Outputs essentially equally expensive?

    2. When dealing with a Timeline graph that has both script and animation outputs, are the animation outputs evaluated at a different point during the update cycle? Is that work threaded during the internal animation update? Just the ProcessFrame part?

    3. Related to #2; when overriding the outputs on a custom TrackAsset to have AnimationPlayableBindings, is the resulting Animation Output updated and processed in the same way as default Animation Track outputs? Does this have any impact on the PrepareData phase of a custom playable connected to this branch?

    4. And more generally; Are any of the PrepareData, PrepareFrame and ProcessFrame phases ever run outside of Evaluate? The documentation on why these particular phases exist (or what happens inbetween them) is quite brief.
     
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516


    1. I've read calling Update manually on an Animator "means your animators will run single-threaded". How much of the cost of an Animator update comes from the graph evaluation? Is calling Evaluate on a playable graph with Animation Outputs essentially equally expensive?

    Yes - Update() (or PlayableDirector.Evaluate()) evaluates the entire graph single threaded, and that is where most of the cost is. An animator controller is a playable graph, as is timeline and the evaluate does a prepare (updates the graphs links and weights) and a Process (actually evaluation of the animation data).

    2. When dealing with a Timeline graph that has both script and animation outputs, are the animation outputs evaluated at a different point during the update cycle? Is that work threaded during the internal animation update? Just the ProcessFrame part?

    Yes - the entire graph in that case is 'Prepared' single threaded, but the Process step of the animation is threaded. The ProcessFrame of the script playables is run on the main thread.

    3. Related to #2; when overriding the outputs on a custom TrackAsset to have AnimationPlayableBindings, is the resulting Animation Output updated and processed in the same way as default Animation Track outputs? Does this have any impact on the PrepareData phase of a custom playable connected to this branch?

    Yes - is is processed the same. PrepareData/PrepareFrame happen single threaded for all of timeline.

    4. And more generally; Are any of the PrepareData, PrepareFrame and ProcessFrame phases ever run outside of Evaluate? The documentation on why these particular phases exist (or what happens inbetween them) is quite brief.

    If by Evaluate() you mean PlayableDirector.Evaluate() or PlayableGraph.Evaluate(), then no. Those are intended to be synchronous evaluations of a graph. When a graph is playing however, Evaluate() isn't called. Those phases are split up and run at different points in the PlayerLoop (but all between Update() & LateUpdate()), and threaded as appropriate.

    I hope that clarifies it a bit.
     
  3. leozzyzheng2

    leozzyzheng2

    Joined:
    Jul 2, 2021
    Posts:
    60
    I'm using 2021.3.2f1 and find PlayableGraph.Evaluate is slow, I have nearly 100 animator and want to use Manual Update mode, so I need call Evaluate rather than use Game Time or Unscale Time.

    But I found PlayableGraph.Evaluate is much slower than use other Update Mode.
    After check the profiler, I found each time I called PlayableGraph.Evaluate, it will wait the job end. But if unity schedule it at Director.ProcessFrame, then it will batch all job and wait only once.

    The time cost is very different.

    So I'm interested that is there anyplace let me input the Manual Update delta time and also schedule it in Director.ProcessFrame?
     
    CBHM likes this.
  4. NGC6543

    NGC6543

    Joined:
    Jun 3, 2015
    Posts:
    228
    Hi @seant_unity, thank you for your answer.
    I also have some question.

    I have a lot of animators with PlayableGraphs, and I'd like to 'sparse-update' animators based on the distance from the main character. Putting simply, animation LOD-ing.

    Your answer above indicates that calling PlayerbleGraph.Evaluate() may incur performance issue. But there aren't any performant way to skip animation frames.

    What would it be the best practice for sparse-update of PlayableGraph?
     
    CBHM likes this.
  5. leozzyzheng2

    leozzyzheng2

    Joined:
    Jul 2, 2021
    Posts:
    60
    I'm using Animator.speed instead of delta time arugment in Update or Evaluate:

    animator.speed = deltaTime you passed to Update / Time.unscaledDeltaTime;
    animator.enable = true;

    Then I disable the animator in LateUpdate since the director will batch update animator before it. It is a little tricky but it works for me. Hopes it will help you.
     
    ModLunar likes this.
  6. NGC6543

    NGC6543

    Joined:
    Jun 3, 2015
    Posts:
    228
    Thanks for sharing your tip!
    I'm curious, have you profiled your setup? Did it work as expected?
     
  7. leozzyzheng2

    leozzyzheng2

    Joined:
    Jul 2, 2021
    Posts:
    60
    Yes, it took 2ms less than the Update method for me on Snapdragon 660 CPU on Android for ~100 animators(you can see almost no Idle on threads which runs the jobs instead of many Idle blocks on those threads if using Update method) analyzed by Profiler Analyzer, so I believe it works.

    I think the preformance will also depends on the complex of your animators and the speed of your device CPU.
     
    Hecocos and NGC6543 like this.
  8. NGC6543

    NGC6543

    Joined:
    Jun 3, 2015
    Posts:
    228
    Thank you for the reply! Have a great day!