[Bf-blender-cvs] [885bb5b137b] master: Depsgraph: Bring timing statistics to the new dependency graph

Sergey Sharybin noreply at git.blender.org
Thu Dec 21 16:33:38 CET 2017


Commit: 885bb5b137b5ea71869b741e6ee7acc1602ab5c6
Author: Sergey Sharybin
Date:   Thu Dec 21 16:14:15 2017 +0100
Branches: master
https://developer.blender.org/rB885bb5b137b5ea71869b741e6ee7acc1602ab5c6

Depsgraph: Bring timing statistics to the new dependency graph

This statistics is only collected when debug_value is different from 0.

Stored in depsgraph node itself, so we can always have access to average data
and other stats which requires persistent storage. This way we also don't waste
time trying to find stats from a separately stored hash map.

===================================================================

M	source/blender/depsgraph/CMakeLists.txt
M	source/blender/depsgraph/DEG_depsgraph_debug.h
A	source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
M	source/blender/depsgraph/intern/eval/deg_eval.cc
A	source/blender/depsgraph/intern/eval/deg_eval_stats.cc
A	source/blender/depsgraph/intern/eval/deg_eval_stats.h
M	source/blender/depsgraph/intern/nodes/deg_node.cc
M	source/blender/depsgraph/intern/nodes/deg_node.h
M	source/blender/makesrna/intern/rna_depsgraph.c

===================================================================

diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index 04fbbbf0915..af2c2ecb67f 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -52,8 +52,10 @@ set(SRC
 	intern/builder/deg_builder_relations_scene.cc
 	intern/builder/deg_builder_transitive.cc
 	intern/debug/deg_debug_relations_graphviz.cc
+	intern/debug/deg_debug_stats_gnuplot.cc
 	intern/eval/deg_eval.cc
 	intern/eval/deg_eval_flush.cc
+	intern/eval/deg_eval_stats.cc
 	intern/nodes/deg_node.cc
 	intern/nodes/deg_node_component.cc
 	intern/nodes/deg_node_id.cc
@@ -82,6 +84,7 @@ set(SRC
 	intern/builder/deg_builder_transitive.h
 	intern/eval/deg_eval.h
 	intern/eval/deg_eval_flush.h
+	intern/eval/deg_eval_stats.h
 	intern/nodes/deg_node.h
 	intern/nodes/deg_node_component.h
 	intern/nodes/deg_node_id.h
diff --git a/source/blender/depsgraph/DEG_depsgraph_debug.h b/source/blender/depsgraph/DEG_depsgraph_debug.h
index e920e34dad3..bc93fcc94cb 100644
--- a/source/blender/depsgraph/DEG_depsgraph_debug.h
+++ b/source/blender/depsgraph/DEG_depsgraph_debug.h
@@ -55,6 +55,11 @@ void DEG_debug_relations_graphviz(const struct Depsgraph *graph,
                                   FILE *stream,
                                   const char *label);
 
+void DEG_debug_stats_gnuplot(const struct Depsgraph *graph,
+                             FILE *stream,
+                             const char *label,
+                             const char *output_filename);
+
 /* ************************************************ */
 
 /* Compare two dependency graphs. */
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
new file mode 100644
index 00000000000..ecef4ff55a7
--- /dev/null
+++ b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
@@ -0,0 +1,126 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2017 Blender Foundation.
+ * All rights reserved.
+ *
+ * Original Author: Sergey Sharybin
+ * Contributor(s): None Yet
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
+ *  \ingroup depsgraph
+ */
+
+#include "DEG_depsgraph_debug.h"
+
+#include <stdarg.h>
+
+#include "BLI_compiler_attrs.h"
+
+#include "intern/depsgraph.h"
+#include "intern/nodes/deg_node_id.h"
+
+#include "util/deg_util_foreach.h"
+
+extern "C" {
+#include "DNA_ID.h"
+} /* extern "C" */
+
+#define NL "\r\n"
+
+namespace DEG {
+namespace {
+
+struct DebugContext {
+	FILE *file;
+	const Depsgraph *graph;
+	const char *label;
+	const char *output_filename;
+};
+
+/* TODO(sergey): De-duplicate with graphviz relation debugger. */
+static void deg_debug_fprintf(const DebugContext &ctx,
+                              const char *fmt,
+                              ...) ATTR_PRINTF_FORMAT(2, 3);
+static void deg_debug_fprintf(const DebugContext &ctx, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	vfprintf(ctx.file, fmt, args);
+	va_end(args);
+}
+
+void write_stats_data(const DebugContext& ctx)
+{
+	deg_debug_fprintf(ctx, "$data << EOD" NL);
+	// TODO(sergey): Sort nodes by time.
+	foreach (const IDDepsNode *id_node, ctx.graph->id_nodes) {
+		// TODO(sergey): Figure out a nice way to define which exact time
+		// we want to show.
+		const double time = id_node->stats.current_time;
+		if (time == 0.0) {
+			continue;
+		}
+		deg_debug_fprintf(ctx, "\"%s\",%f" NL,
+		                  id_node->id->name + 2,
+		                  time);
+	}
+	deg_debug_fprintf(ctx, "EOD" NL);
+}
+
+void deg_debug_stats_gnuplot(const DebugContext& ctx)
+{
+	// Data itself.
+	write_stats_data(ctx);
+	// Optional label.
+	if (ctx.label && ctx.label[0]) {
+		deg_debug_fprintf(ctx, "set title \"%s\"" NL, ctx.label);
+	}
+	// Rest of the commands.
+	// TODO(sergey): Need to decide on the resolution somehow.
+	deg_debug_fprintf(ctx, "set terminal pngcairo size 1920,1080" NL);
+	deg_debug_fprintf(ctx, "set output \"%s\"" NL, ctx.output_filename);
+	deg_debug_fprintf(ctx, "set grid" NL);
+	deg_debug_fprintf(ctx, "set datafile separator ','" NL);
+	deg_debug_fprintf(ctx, "set style fill solid" NL);
+	deg_debug_fprintf(ctx, "plot \"$data\" using " \
+	                       "($2*0.5):0:($2*0.5):(0.2):yticlabels(1) "
+	                       "with boxxyerrorbars t '' lt rgb \"#406090\"" NL);
+
+}
+
+}  // namespace
+}  // namespace DEG
+
+void DEG_debug_stats_gnuplot(const Depsgraph *depsgraph,
+                             FILE *f,
+                             const char *label,
+                             const char *output_filename)
+{
+	if (depsgraph == NULL) {
+		return;
+	}
+	DEG::DebugContext ctx;
+	ctx.file = f;
+	ctx.graph = (DEG::Depsgraph *)depsgraph;
+	ctx.label = label;
+	ctx.output_filename = output_filename;
+	DEG::deg_debug_stats_gnuplot(ctx);
+}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index c5100856e83..09d25be41d6 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -48,6 +48,7 @@ extern "C" {
 #include "atomic_ops.h"
 
 #include "intern/eval/deg_eval_flush.h"
+#include "intern/eval/deg_eval_stats.h"
 #include "intern/nodes/deg_node.h"
 #include "intern/nodes/deg_node_component.h"
 #include "intern/nodes/deg_node_id.h"
@@ -74,6 +75,7 @@ struct DepsgraphEvalState {
 	EvaluationContext *eval_ctx;
 	Depsgraph *graph;
 	unsigned int layers;
+	bool do_stats;
 };
 
 static void deg_task_run_func(TaskPool *pool,
@@ -86,7 +88,14 @@ static void deg_task_run_func(TaskPool *pool,
 	/* Sanity checks. */
 	BLI_assert(!node->is_noop() && "NOOP nodes should not actually be scheduled");
 	/* Perform operation. */
-	node->evaluate(state->eval_ctx);
+	if (state->do_stats) {
+		const double start_time = PIL_check_seconds_timer();
+		node->evaluate(state->eval_ctx);
+		node->stats.current_time += PIL_check_seconds_timer() - start_time;
+	}
+	else {
+		node->evaluate(state->eval_ctx);
+	}
 	/* Schedule children. */
 	BLI_task_pool_delayed_push_begin(pool, thread_id);
 	schedule_children(pool, state->graph, node, state->layers, thread_id);
@@ -145,10 +154,14 @@ static void calculate_pending_parents(Depsgraph *graph, unsigned int layers)
 
 static void initialize_execution(DepsgraphEvalState *state, Depsgraph *graph)
 {
+	const bool do_stats = state->do_stats;
 	calculate_pending_parents(graph, state->layers);
 	/* Clear tags and other things which needs to be clear. */
 	foreach (OperationDepsNode *node, graph->operations) {
 		node->done = 0;
+		if (do_stats) {
+			node->stats.reset_current();
+		}
 	}
 }
 
@@ -250,6 +263,7 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
 	state.eval_ctx = eval_ctx;
 	state.graph = graph;
 	state.layers = layers;
+	state.do_stats = (G.debug_value != 0);
 	/* Set up task scheduler and pull for threaded evaluation. */
 	TaskScheduler *task_scheduler;
 	bool need_free_scheduler;
@@ -268,6 +282,13 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx,
 	schedule_graph(task_pool, graph, layers);
 	BLI_task_pool_work_and_wait(task_pool);
 	BLI_task_pool_free(task_pool);
+	/* Finalize statistics gathering. This is because we only gather single
+	 * operation timing here, without aggregating anything to avoid any extra
+	 * synchronization.
+	 */
+	if (state.do_stats) {
+		deg_eval_stats_aggregate(graph);
+	}
 	/* Clear any uncleared tags - just in case. */
 	deg_graph_clear_tags(graph);
 	if (need_free_scheduler) {
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_stats.cc b/source/blender/depsgraph/intern/eval/deg_eval_stats.cc
new file mode 100644
index 00000000000..52ce744cc0a
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_stats.cc
@@ -0,0 +1,70 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2017 Blender Foundation.
+ * All rights reserved.
+ *
+ * Original Author: Sergey Sharybin
+ * Contributor(s): None Yet
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/depsgraph/intern/eval/deg_eval_stats.cc
+ *  \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_stats.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+
+#include "intern/depsgraph.h"
+
+#include "intern/nodes/deg_node.h"
+#include "intern/nodes/deg_node_component.h"
+#include "intern/nodes/deg_node_id.h"
+#include "intern/nodes/deg_node_operation.h"
+
+#include "util/deg_util_foreach.h"
+
+namespace DEG {
+
+void deg_eval_stats_aggregate(Depsgraph *graph)
+{
+	/* Reset current evaluation stats for ID and component nodes.
+	 * Those are not filled in by the evaluation engine.
+	 */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list