Note: This is an archived version of the Blender Developer Wiki (archived 2024). The current developer documentation is available on developer.blender.org/docs.

User:Jbakker/projects/FasterAnimationPlayback/Spring Scene Analysis

Spring Scene Analysis

In order to find areas of improvement I went over the animation scenes of the Spring open movie. These scenes can be found at https://cloud.blender.org/p/spring/5cb07dbb808c0e74d46eed37.

BaseLine

Used Hardware

  • AMD Ryzen 1700
  • 16GB Ram 2400mhz
  • AMD Vega 64
  • Ubuntu 18.04.3
  • Attached to a 4k screen

Used Additional Software

hotspot-v1.2.0-x86_64.AppImage

Blender

  • Blender 2.83 master [cc516b82ef]
  • Compiled with RelWithDebInfo

Apply the next patch.

diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc
index 7e7ab07825f..3ea5bda80bf 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cc
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cc
@@ -29,6 +29,8 @@
 #include "BLI_listbase.h"
 #include "BLI_utildefines.h"
 
+#include "PIL_time_utildefines.h"
+
 extern "C" {
 #include "BKE_scene.h"
 
@@ -68,6 +70,7 @@ void DEG_evaluate_on_refresh(Main *bmain, Depsgraph *graph)
 /* Frame-change happened for root scene that graph belongs to. */
 void DEG_evaluate_on_framechange(Main *bmain, Depsgraph *graph, float ctime)
 {
+  TIMEIT_START_AVERAGED(DEG_evaluate_on_framechange);
   DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
   deg_graph->ctime = ctime;
   /* Update time on primary timesource. */
@@ -82,6 +85,7 @@ void DEG_evaluate_on_framechange(Main *bmain, Depsgraph *graph, float ctime)
   /* Perform recalculation updates. */
   DEG::deg_evaluate_on_refresh(deg_graph);
   deg_graph->need_update_time = false;
+  TIMEIT_END_AVERAGED(DEG_evaluate_on_framechange);
 }
 
 bool DEG_needs_eval(Depsgraph *graph)
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index adaa1dd6151..95f03ff239a 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -73,6 +73,8 @@
 
 #include "IMB_colormanagement.h"
 
+#include "PIL_time_utildefines.h"
+
 #include "RE_engine.h"
 #include "RE_pipeline.h"
 
@@ -1410,7 +1412,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
                              GPUViewport *viewport,
                              const bContext *evil_C)
 {
-
+  TIMEIT_START_AVERAGED(DRW_draw_render_loop_ex);
   Scene *scene = DEG_get_evaluated_scene(depsgraph);
   ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
   RegionView3D *rv3d = region->regiondata;
@@ -1534,6 +1536,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
   /* Avoid accidental reuse. */
   drw_state_ensure_not_reused(&DST);
 #endif
+  TIMEIT_END_AVERAGED(DRW_draw_render_loop_ex);
 }
 
 void DRW_draw_render_loop(struct Depsgraph *depsgraph,

Metrics

Frames Per Second

The actual frames per second that the user can verify.

  • Start Blender
  • load Scene to test
  • start playback.
  • look at the FPS indicated in the UI.

Depsgraph Time

  • Start Blender
  • Load Scene to test
  • Set the main animator 3d view of the file to full screen (crtl-alt-space)
  • start playback
  • after a minute stop animation
  • in console look at the average figure

Draw Time

  • Start Blender
  • Load Scene to test
  • Set the main animator 3d view of the file to full screen (crtl-alt-space)
  • start playback
  • after a minute stop animation
  • in console look at the average figure

Note this figure isn't accurate. I want to redo this and record the last frame render time. The average includes too many samples when starting blender that are really fast as they show the same scene. I updated some scenes with the new figures, but still downloading the other scenes to do a retest.

Flame Graph

  • start blender via perf ()
  • Load Scene to test
  • Start playback
  • After a minute stop playback
  • Quit blender
  • load perf in hotspot
  • Go to Flame Graph
  • select the timeframe where the animation is playing. Filter in on selection
  • make a screen shot of the result.
sudo perf record -o /home/jeroen/reports/perf.data --call-graph dwarf --sample-cpu /home/jeroen/blender-git/build_linux/bin/blender

Scenes

01_025_A.anim.blend

  • FPS: 9.5
  • time averaged (DEG_evaluate_on_framechange): 0.073477
  • time end (DRW_draw_render_loop_ex): 0.008590

20200319 01 025 A.flamegraph.png

02_020_a.anim.blend

  • 8.8 FPS
  • time averaged (DEG_evaluate_on_framechange): 0.052770
  • time end (DRW_draw_render_loop_ex): 0.030936

20200319 02 020 A.flamegraph.png

02_040_a.anim.blend

  • 3.9 FPS
  • time averaged (DEG_evaluate_on_framechange): 0.113819
  • time end (DRW_draw_render_loop_ex): 0.063630

20200319 02 040 A.flamegraph.png

02_055_A.anim.blend

  • 14.25 FPS
  • time averaged (DEG_evaluate_on_framechange): 0.036567 (total: 35.616497, in 974 runs)
  • time end (DRW_draw_render_loop_ex): 0.023571

20200320 02 055 A.flamegraph.png

03_005_A.anim.blend

  • 7.8 FPS
  • time averaged (DEG_evaluate_on_framechange): 0.053629
  • time end (DRW_draw_render_loop_ex): 0.041649

20200320 03 005 A.flamegraph.png

This file has a fluid modifier... I think it used to have a smoke simulation, but that got converted to a fluid modifier due to mantaflow. It also seems that a lot of allocations happen during the fluid modifier. We might find some low hanging fruit here.

03_035_A.anim.blend

  • 3.4 FPS
  • time averaged (DEG_evaluate_on_framechange): 0.159914
  • time end (DRW_draw_render_loop_ex): 0.080717

20200320 03 035 A.flamegraph.png

04_070_B.anim.blend

  • 2.9 FPS
  • time averaged (DEG_evaluate_on_framechange): 0.187593
  • time averaged (DRW_draw_render_loop_ex): 0.076978


05_030_A.anim.blend

  • 2.9 FPS
  • time averaged (DEG_evaluate_on_framechange): 0.172747
  • time end (DRW_draw_render_loop_ex): 0.114026

20200320 05 030 A.flamegraph.png

05_025_A.anim.blend

  • 6.5 FPS
  • time averaged (DEG_evaluate_on_framechange): 0.059501
  • time end (DRW_draw_render_loop_ex): 0.067520

20200320 05 025 A.flamegraph.png

First impression

Still need to do a more in-depth research to get some actual findings. This is what I have so far, but it should not be interpreted as my final result.

Attention points

  • Spring has been made using Blender 2.80 (alpha). In Blender 2.83 the scene behave different than in Blender 2.80. Some of these changes that I am aware of are
    • Workbench has been rewritten
    • Overlay engine has been rewritten
    • Manta flow is used for smoke simulations.
    • Different threading model (BTT)
  • Some scenes uses a smoke simulation. as the smoke sim has been migrated to manta flow it doesn't reflect the action scenes animators are working in.
    • TODO: Check with Hjalti/Andy how to handle this situation for this performance project.
    • Mantaflow is fairly new and might be improved as I do see many allocs/frees.
  • Threading could be improved in different areas. A lot of time is spend in the current_vcpu function in linux. (for example 05_025_A)
  • Could be based on the slow single threading or the GPU driver but I do see a long single threaded execution in every frame. I do think this is related to the whole wm loop, drawmanager/opengl and driver. Can we use the idle time of the other threads to do something for the next frame? Hardest thing is to accurate determine what is the next frame.
  • When an area is maximized there are still other areas that can be redrawn. Seems not needed.