[Bf-blender-cvs] [8a42b3909f3] blender2.8: Subsurf: Add basic statistics to help benchmarking

Sergey Sharybin noreply at git.blender.org
Fri Jul 20 09:28:12 CEST 2018


Commit: 8a42b3909f33d90b065eec2b8eb342df0a1fb659
Author: Sergey Sharybin
Date:   Thu Jul 19 16:27:18 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB8a42b3909f33d90b065eec2b8eb342df0a1fb659

Subsurf: Add basic statistics to help benchmarking

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

M	source/blender/blenkernel/BKE_subdiv.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/subdiv.c
M	source/blender/blenkernel/intern/subdiv_eval.c
M	source/blender/blenkernel/intern/subdiv_mesh.c
A	source/blender/blenkernel/intern/subdiv_stats.c
M	source/blender/modifiers/intern/MOD_subsurf.c

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

diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index 45316e3cc91..a1792866255 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -53,6 +53,40 @@ typedef struct SubdivSettings {
 	eSubdivFVarLinearInterpolation fvar_linear_interpolation;
 } SubdivSettings;
 
+/* NOTE: Order of enumerators MUST match order of values in SubdivStats. */
+typedef enum eSubdivStatsValue {
+	SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME = 0,
+	SUBDIV_STATS_SUBDIV_TO_MESH,
+	SUBDIV_STATS_EVALUATOR_CREATE,
+	SUBDIV_STATS_EVALUATOR_REFINE,
+
+	NUM_SUBDIV_STATS_VALUES,
+} eSubdivStatsValue;
+
+typedef struct SubdivStats {
+	union {
+		struct {
+			/* Time spend on creating topology refiner, which includes time
+			 * spend on conversion from Blender data to OpenSubdiv data, and
+			 * time spend on topology orientation on OpenSubdiv C-API side.
+			 */
+			double topology_refiner_creation_time;
+			/* Total time spent in BKE_subdiv_to_mesh(). */
+			double subdiv_to_mesh_time;
+			/* Time spent on evaluator creation from topology refiner. */
+			double evaluator_creation_time;
+			/* Time spent on evaluator->refine(). */
+			double evaluator_refine_time;
+		};
+		double values_[NUM_SUBDIV_STATS_VALUES];
+	};
+
+	/* Per-value timestamp on when corresponding BKE_subdiv_stats_begin() was
+	 * called.
+	 */
+	double begin_timestamp_[NUM_SUBDIV_STATS_VALUES];
+} SubdivStats;
+
 typedef struct Subdiv {
 	/* Settings this subdivision surface is created for.
 	 *
@@ -88,8 +122,19 @@ typedef struct Subdiv {
 
 	/* CPU side evaluator. */
 	struct OpenSubdiv_Evaluator *evaluator;
+
+	SubdivStats stats;
 } Subdiv;
 
+/* =============================== STATISTICS =============================== */
+
+void BKE_subdiv_stats_init(SubdivStats *stats);
+
+void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value);
+void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value);
+
+void BKE_subdiv_stats_print(const SubdivStats *stats);
+
 /* ============================== CONSTRUCTION ============================== */
 
 Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 0517eb8e732..01910bffdb0 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -191,6 +191,7 @@ set(SRC
 	intern/subdiv_converter_mesh.c
 	intern/subdiv_eval.c
 	intern/subdiv_mesh.c
+	intern/subdiv_stats.c
 	intern/subsurf_ccg.c
 	intern/suggestions.c
 	intern/text.c
diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c
index 72cd39983b9..794da2d3477 100644
--- a/source/blender/blenkernel/intern/subdiv.c
+++ b/source/blender/blenkernel/intern/subdiv.c
@@ -63,6 +63,9 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
                                       struct OpenSubdiv_Converter *converter)
 {
 #ifdef WITH_OPENSUBDIV
+	SubdivStats stats;
+	BKE_subdiv_stats_init(&stats);
+	BKE_subdiv_stats_begin(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME);
 	OpenSubdiv_TopologyRefinerSettings topology_refiner_settings;
 	topology_refiner_settings.level = settings->level;
 	topology_refiner_settings.is_adaptive = settings->is_adaptive;
@@ -77,6 +80,8 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
 	subdiv->topology_refiner = osd_topology_refiner;
 	subdiv->evaluator = NULL;
 	update_subdiv_after_topology_change(subdiv);
+	BKE_subdiv_stats_end(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME);
+	subdiv->stats = stats;
 	return subdiv;
 #else
 	UNUSED_VARS(settings, converter);
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
index 0ab19fc8df5..4c2ed07cdfa 100644
--- a/source/blender/blenkernel/intern/subdiv_eval.c
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -46,8 +46,10 @@ void BKE_subdiv_eval_begin(Subdiv *subdiv)
 {
 #ifdef WITH_OPENSUBDIV
 	if (subdiv->evaluator == NULL) {
+		BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
 		subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner(
 		        subdiv->topology_refiner);
+		BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
 	}
 	else {
 		/* TODO(sergey): Check for topology change. */
@@ -112,7 +114,9 @@ void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh)
 		break;
 	}
 	/* Update evaluator to the new coarse geometry. */
+	BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE);
 	subdiv->evaluator->refine(subdiv->evaluator);
+	BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE);
 #else
 	UNUSED_VARS(subdiv, mesh);
 #endif
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
index 7baf03e7265..83f2069ea0f 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
@@ -912,6 +912,7 @@ Mesh *BKE_subdiv_to_mesh(
         const SubdivToMeshSettings *settings,
         const Mesh *coarse_mesh)
 {
+	BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
 	/* Make sure evaluator is up to date with possible new topology, and that
 	 * is is refined for the new positions of coarse vertices.
 	 */
@@ -946,5 +947,6 @@ Mesh *BKE_subdiv_to_mesh(
 	                        &ctx,
 	                        subdiv_eval_task,
 	                        &parallel_range_settings);
+	BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
 	return result;
 }
diff --git a/source/blender/blenkernel/intern/subdiv_stats.c b/source/blender/blenkernel/intern/subdiv_stats.c
new file mode 100644
index 00000000000..5da63fdbacb
--- /dev/null
+++ b/source/blender/blenkernel/intern/subdiv_stats.c
@@ -0,0 +1,80 @@
+/*
+ * ***** 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) 2018 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/subdiv_stats.c
+ *  \ingroup bke
+ */
+
+#include "BKE_subdiv.h"
+
+#include <stdio.h>
+
+#include "PIL_time.h"
+
+void BKE_subdiv_stats_init(SubdivStats *stats)
+{
+	stats->topology_refiner_creation_time = 0.0;
+	stats->subdiv_to_mesh_time = 0.0;
+	stats->evaluator_creation_time = 0.0;
+	stats->evaluator_refine_time = 0.0;
+}
+
+void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value)
+{
+	stats->begin_timestamp_[value] = PIL_check_seconds_timer();
+}
+
+void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value)
+{
+	stats->values_[value] =
+	        PIL_check_seconds_timer() - stats->begin_timestamp_[value];
+}
+
+void BKE_subdiv_stats_print(const SubdivStats *stats)
+{
+#define STATS_PRINT_TIME(stats, value, description)                 \
+	do {                                                            \
+		if ((stats)->value > 0.0) {                                 \
+		  printf("  %s: %f (sec)\n", description, (stats)->value);  \
+		}                                                           \
+	} while (false)
+
+	printf("Subdivision surface statistics:\n");
+
+	STATS_PRINT_TIME(stats,
+	                 topology_refiner_creation_time,
+	                 "Topology refiner creation time");
+	STATS_PRINT_TIME(stats,
+	                 subdiv_to_mesh_time,
+	                 "Subdivision to mesh time");
+	STATS_PRINT_TIME(stats,
+	                 evaluator_creation_time,
+	                 "Evaluator creation time");
+	STATS_PRINT_TIME(stats,
+	                 evaluator_refine_time,
+	                 "Evaluator refine time");
+
+#undef STATS_PRINT_TIME
+}
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index c92845a24eb..08dc7c92693 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -247,6 +247,7 @@ static Mesh *applyModifier_subdiv(ModifierData *md,
 	subdiv_mesh_settings_init(&mesh_settings, &subdiv_settings);
 	result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh);
 	/* TODO(sergey): Cache subdiv somehow. */
+	// BKE_subdiv_stats_print(&subdiv->stats);
 	BKE_subdiv_free(subdiv);
 	return result;
 }



More information about the Bf-blender-cvs mailing list