[Bf-blender-cvs] [cacb43e] depsgraph_refactor: Record basic statistics on depsgraph timing, if enabled in user prefs.

Lukas Tönne noreply at git.blender.org
Tue May 27 17:10:36 CEST 2014


Commit: cacb43e04ccaa88f3fbe208ec3ba2f5ca75005dd
Author: Lukas Tönne
Date:   Tue May 27 17:01:26 2014 +0200
https://developer.blender.org/rBcacb43e04ccaa88f3fbe208ec3ba2f5ca75005dd

Record basic statistics on depsgraph timing, if enabled in user prefs.

This works with a (C style) `DepsgraphStats` struct, which holds a hash
table containing per-ID block info. These ID info structs in turn can
optionally have more detailed per-component info (currently never
generated, this would have to be enabled per ID by the user in some way).

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

M	source/blender/depsgraph/DEG_depsgraph_debug.h
M	source/blender/depsgraph/intern/depsgraph_debug.cpp
M	source/blender/depsgraph/intern/depsgraph_debug.h
M	source/blender/depsgraph/intern/depsgraph_eval.cpp
M	source/blender/makesrna/intern/rna_scene.c

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

diff --git a/source/blender/depsgraph/DEG_depsgraph_debug.h b/source/blender/depsgraph/DEG_depsgraph_debug.h
index e990fe3..0ebcc59 100644
--- a/source/blender/depsgraph/DEG_depsgraph_debug.h
+++ b/source/blender/depsgraph/DEG_depsgraph_debug.h
@@ -29,13 +29,48 @@
 #ifndef __DEG_DEPSGRAPH_DEBUG_H__
 #define __DEG_DEPSGRAPH_DEBUG_H__
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "DNA_listBase.h"
+
+struct DepsgraphSettings;
+struct GHash;
+struct ID;
+
 struct Depsgraph;
 struct DepsNode;
 struct DepsRelation;
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+/* ************************************************ */
+/* Statistics */
+
+typedef struct DepsgraphStatsTimes {
+	float last;
+} DepsgraphStatsTimes;
+
+typedef struct DepsgraphStatsComponent {
+	struct DepsgraphStatsComponent *next, *prev;
+	
+	char name[64];
+	DepsgraphStatsTimes times;
+} DepsgraphStatsComponent;
+
+typedef struct DepsgraphStatsID {
+	struct ID *id;
+	
+	DepsgraphStatsTimes times;
+	ListBase components;
+} DepsgraphStatsID;
+
+typedef struct DepsgraphStats {
+	struct GHash *id_stats;
+} DepsgraphStats;
+
+struct DepsgraphStats *DEG_stats(void);
+
+void DEG_stats_verify(struct DepsgraphSettings *settings);
 
 /* ************************************************ */
 /* Graphviz Debugging */
diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cpp b/source/blender/depsgraph/intern/depsgraph_debug.cpp
index c4c6b62..e207c7b 100644
--- a/source/blender/depsgraph/intern/depsgraph_debug.cpp
+++ b/source/blender/depsgraph/intern/depsgraph_debug.cpp
@@ -32,6 +32,7 @@
 
 extern "C" {
 #include "BLI_blenlib.h"
+#include "BLI_listbase.h"
 #include "BLI_ghash.h"
 #include "BLI_utildefines.h"
 
@@ -40,6 +41,7 @@ extern "C" {
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_sequence_types.h"
+#include "DNA_userdef_types.h"
 
 #include "BKE_idcode.h"
 
@@ -696,11 +698,22 @@ void DEG_debug_eval_step(const char *message) {}
 
 /* ************************************************ */
 
+static string get_component_name(eDepsNode_Type type, const string &name = "")
+{
+	DepsNodeFactory *factory = DEG_get_node_factory(type);
+	if (name.empty())
+		return string(factory->tname());
+	else
+		return string_format("%s | %s", factory->tname().c_str(), name.c_str());
+}
+
 void DepsgraphDebug::eval_begin(eEvaluationContextType context_type)
 {
+	verify_stats(&U.depsgraph_settings);
+	reset_stats();
 }
 
-void DepsgraphDebug::eval_end(eEvaluationContextType context_type, double time)
+void DepsgraphDebug::eval_end(eEvaluationContextType context_type)
 {
 }
 
@@ -712,14 +725,132 @@ void DepsgraphDebug::eval_step(eEvaluationContextType context_type, const char *
 
 void DepsgraphDebug::task_started(const DepsgraphTask &task)
 {
+//	BLI_mutex_lock(&stats_mutex);
+//	BLI_mutex_unlock(&stats_mutex);
 }
 
 void DepsgraphDebug::task_completed(const DepsgraphTask &task, double time)
 {
+	if (!stats)
+		return;
+	
+	BLI_mutex_lock(&stats_mutex);
+	
 	OperationDepsNode *node = task.node;
 	ComponentDepsNode *comp = node->owner;
 	ID *id = comp->owner->id;
-	printf("%s %s : %s took %f ms\n", BKE_idcode_to_name(GS(id->name)), id->name+2, comp->name.c_str(), time);
+	
+//	printf("%s %s : %s took %f ms\n", BKE_idcode_to_name(GS(id->name)), id->name+2, comp->name.c_str(), time);
+	
+	DepsgraphStatsID *id_stats = get_id_stats(id, true);
+	id_stats->times.last += time;
+	
+	/* XXX TODO use something like: if (id->flag & ID_DEG_DETAILS) {...} */
+	if (0) {
+		/* XXX component name usage needs cleanup! currently mixes identifier and description strings! */
+		DepsgraphStatsComponent *comp_stats = get_component_stats(id, get_component_name(comp->type, comp->name), true);
+		comp_stats->times.last += time;
+	}
+	
+	BLI_mutex_unlock(&stats_mutex);
 }
 
 /* ************************************************ */
+/* Statistics */
+
+DepsgraphStats *DepsgraphDebug::stats = NULL;
+ThreadMutex DepsgraphDebug::stats_mutex;
+
+/* GHash callback */
+static void deg_id_stats_free(void *val)
+{
+	DepsgraphStatsID *id_stats = (DepsgraphStatsID *)val;
+
+	if (id_stats) {
+		BLI_freelistN(&id_stats->components);
+		MEM_freeN(id_stats);
+	}
+}
+
+void DepsgraphDebug::stats_init()
+{
+	if (!stats) {
+		stats = (DepsgraphStats *)MEM_callocN(sizeof(DepsgraphStats), "Depsgraph Stats");
+		stats->id_stats = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "Depsgraph ID Stats Hash");
+		
+		BLI_mutex_init(&stats_mutex);
+	}
+}
+
+void DepsgraphDebug::stats_free()
+{
+	if (stats) {
+		BLI_mutex_end(&stats_mutex);
+		
+		BLI_ghash_free(stats->id_stats, NULL, deg_id_stats_free);
+		MEM_freeN(stats);
+		stats = NULL;
+	}
+}
+
+void DepsgraphDebug::verify_stats(DepsgraphSettings *settings)
+{
+	if (settings->flag & USER_DEG_STATS) {
+		stats_init();
+	}
+	else {
+		stats_free();
+	}
+}
+
+void DepsgraphDebug::reset_stats()
+{
+	if (!stats)
+		return;
+	
+	BLI_ghash_clear(stats->id_stats, NULL, deg_id_stats_free);
+}
+
+DepsgraphStatsID *DepsgraphDebug::get_id_stats(ID *id, bool create)
+{
+	DepsgraphStatsID *id_stats = (DepsgraphStatsID *)BLI_ghash_lookup(stats->id_stats, id);
+	
+	if (!id_stats && create) {
+		id_stats = (DepsgraphStatsID *)MEM_callocN(sizeof(DepsgraphStatsID), "Depsgraph ID Stats");
+		id_stats->id = id;
+		
+		BLI_ghash_insert(stats->id_stats, id, id_stats);
+	}
+	
+	return id_stats;
+}
+
+DepsgraphStatsComponent *DepsgraphDebug::get_component_stats(DepsgraphStatsID *id_stats, const string &name, bool create)
+{
+	DepsgraphStatsComponent *comp_stats;
+	for (comp_stats = (DepsgraphStatsComponent *)id_stats->components.first; comp_stats; comp_stats = comp_stats->next) {
+		if (STREQ(comp_stats->name, name.c_str()))
+			break;
+	}
+	
+	if (!comp_stats && create) {
+		comp_stats = (DepsgraphStatsComponent *)MEM_callocN(sizeof(DepsgraphStatsComponent), "Depsgraph Component Stats");
+		BLI_strncpy(comp_stats->name, name.c_str(), sizeof(comp_stats->name));
+		
+		BLI_addtail(&id_stats->components, comp_stats);
+	}
+	
+	return comp_stats;
+}
+
+/* ------------------------------------------------ */
+
+DepsgraphStats *DEG_stats(void)
+{
+	return DepsgraphDebug::stats;
+}
+
+void DEG_stats_verify(DepsgraphSettings *settings)
+{
+	DepsgraphDebug::verify_stats(settings);
+}
diff --git a/source/blender/depsgraph/intern/depsgraph_debug.h b/source/blender/depsgraph/intern/depsgraph_debug.h
index 10fb34a..e3a1b29 100644
--- a/source/blender/depsgraph/intern/depsgraph_debug.h
+++ b/source/blender/depsgraph/intern/depsgraph_debug.h
@@ -38,19 +38,44 @@ extern "C" {
 }
 
 #include "DEG_depsgraph_debug.h"
-
 #include "DEG_depsgraph.h"
 
+#include "depsgraph_util_string.h"
+#include "depsgraph_util_thread.h"
+
+struct DepsgraphStats;
+struct DepsgraphStatsID;
+struct DepsgraphStatsComponent;
+struct DepsgraphSettings;
+
 struct Depsgraph;
 struct DepsgraphTask;
 
 struct DepsgraphDebug {
+	static DepsgraphStats *stats;
+	
+	static void stats_init();
+	static void stats_free();
+	
+	static void verify_stats(DepsgraphSettings *settings);
+	static void reset_stats();
+	
 	static void eval_begin(eEvaluationContextType context_type);
-	static void eval_end(eEvaluationContextType context_type, double time);
+	static void eval_end(eEvaluationContextType context_type);
 	static void eval_step(eEvaluationContextType context_type, const char *message);
 	
 	static void task_started(const DepsgraphTask &task);
 	static void task_completed(const DepsgraphTask &task, double time);
+	
+protected:
+	static ThreadMutex stats_mutex;
+	
+	static DepsgraphStatsID *get_id_stats(ID *id, bool create);
+	static DepsgraphStatsComponent *get_component_stats(DepsgraphStatsID *id_stats, const string &name, bool create);
+	static DepsgraphStatsComponent *get_component_stats(ID *id, const string &name, bool create)
+	{
+		return get_component_stats(get_id_stats(id, create), name, create);
+	}
 };
 
 #endif // __DEPSGRAPH_DEBUG_H__
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cpp b/source/blender/depsgraph/intern/depsgraph_eval.cpp
index 2ea768d..94c9aed 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cpp
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cpp
@@ -82,6 +82,8 @@ void DEG_threaded_init(void)
 /* Free threading lock - called during application shutdown */
 void DEG_threaded_exit(void)
 {
+	DepsgraphDebug::stats_free();
+	
 	DepsgraphTaskScheduler::exit();
 	deg_simulate_eval_free();
 }
@@ -174,12 +176,14 @@ void DEG_evaluate_on_refresh(Depsgraph *graph, eEvaluationContextType context_ty
 		calculate_eval_priority(node);
 	}
 	
-	DepsgraphDebug::eval_step(context_type, "Eval Priority Calculation");
+	DepsgraphDebug::eval_begin(context_type);
 	
 	schedule_graph(task_pool, graph, context_type);
 	
 	task_pool.wait();
 	
+	DepsgraphDebug::eval_end(context_type);
+	
 	/* clear any uncleared tags - just in case */
 	DEG_graph_clear_tags(graph);
 }
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 44e9f6d..b3c55dc 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1541,35 +1541,7 @@ static char *rna_MeshStatVis_path(PointerRNA *UNUSED(ptr))
 	return BLI_strdup("tool_settings.statvis");
 }
 
-
 #pragma message("DEPSGRAPH PORTING XXX: The depsgraph_rebuild function in scene RNA is temporary")
-
-typedef struct SceneDepsgraphDebugInfo {
-	const char *filename;
-	int step;
-	const Depsgraph *graph;
-} SceneDepsgraphDebugInfo;
-
-/* generic debug output function */
-static void rna_Scene_depsgraph_debug(SceneDepsgraphDebugInfo *info, void *UNUSED(elem))
-{
-	char filename[FILE_MAX];
-	char label[256];
-	FILE *f;
-	
-	BLI_snprintf(filename, sizeof(filename), "%s_%04d", info->filename, info->step);
-	f = fopen(filename, "w");
-	if (f == NULL)
-		return;
-	
-	BLI_snprintf(label, sizeof(label), "Build Step #%d", info->step);
-	DEG_debug_graphviz(info->graph, f, label, false);
-	
-	fclose(f);
-	
-	++info->step;
-}
-
 static void rna_Scene_depsgraph_rebuild(Scene *scene, Main *bmain)
 {
 	if (scene->depsgraph)




More information about the Bf-blender-cvs mailing list