[Bf-blender-cvs] [347410a322] master: Depsgraph: Remove workarounds from depsgraph for keeping threads alive

Sergey Sharybin noreply at git.blender.org
Tue Mar 7 17:33:41 CET 2017


Commit: 347410a322c4a356b7111a059ceb89626c8859a5
Author: Sergey Sharybin
Date:   Fri Mar 3 10:58:53 2017 +0100
Branches: master
https://developer.blender.org/rB347410a322c4a356b7111a059ceb89626c8859a5

Depsgraph: Remove workarounds from depsgraph for keeping threads alive

This is something what should be done in the task scheduler instead
with local thread queues so we handle this in a single place.

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

M	source/blender/depsgraph/intern/eval/deg_eval.cc
M	source/blender/depsgraph/intern/eval/deg_eval_flush.cc

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

diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index a5f268aac8..23d6f0e2ef 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -95,105 +95,38 @@ static void deg_task_run_func(TaskPool *pool,
 	/* Should only be the case for NOOPs, which never get to this point. */
 	BLI_assert(node->evaluate);
 
-	while (true) {
-		/* Get context. */
-		/* TODO: Who initialises this? "Init" operations aren't able to
-		 * initialise it!!!
-		 */
-		/* TODO(sergey): We don't use component contexts at this moment. */
-		/* ComponentDepsNode *comp = node->owner; */
-		BLI_assert(node->owner != NULL);
-
-		/* Since we're not leaving the thread for until the graph branches it is
-		 * possible to have NO-OP on the way. for which evaluate() will be NULL.
-		 * but that's all fine, we'll just scheduler it's children.
-		 */
-		if (node->evaluate) {
+	/* Get context. */
+	/* TODO: Who initialises this? "Init" operations aren't able to
+	 * initialise it!!!
+	 */
+	/* TODO(sergey): We don't use component contexts at this moment. */
+	/* ComponentDepsNode *comp = node->owner; */
+	BLI_assert(node->owner != NULL);
+
+	/* Since we're not leaving the thread for until the graph branches it is
+	 * possible to have NO-OP on the way. for which evaluate() will be NULL.
+	 * but that's all fine, we'll just scheduler it's children.
+	 */
+	if (node->evaluate) {
 			/* Take note of current time. */
 #ifdef USE_DEBUGGER
-			double start_time = PIL_check_seconds_timer();
-			DepsgraphDebug::task_started(state->graph, node);
+		double start_time = PIL_check_seconds_timer();
+		DepsgraphDebug::task_started(state->graph, node);
 #endif
 
-			/* Perform operation. */
-			node->evaluate(state->eval_ctx);
+		/* Perform operation. */
+		node->evaluate(state->eval_ctx);
 
 			/* Note how long this took. */
 #ifdef USE_DEBUGGER
-			double end_time = PIL_check_seconds_timer();
-			DepsgraphDebug::task_completed(state->graph,
-			                               node,
-			                               end_time - start_time);
+		double end_time = PIL_check_seconds_timer();
+		DepsgraphDebug::task_completed(state->graph,
+		                               node,
+		                               end_time - start_time);
 #endif
-		}
-
-		/* If there's only one outgoing link we try to immediately switch to
-		 * that node evaluation, without leaving the thread.
-		 *
-		 * It's only doable if the child don't have extra relations or all they
-		 * are satisfied.
-		 *
-		 * TODO(sergey): Checks here can be de-duplicated with the ones from
-		 * schedule_node(), however, how to do it nicely?
-		 */
-		if (node->outlinks.size() == 1) {
-			DepsRelation *rel = node->outlinks[0];
-			OperationDepsNode *child = (OperationDepsNode *)rel->to;
-			BLI_assert(child->type == DEPSNODE_TYPE_OPERATION);
-			if (!child->scheduled) {
-				unsigned int id_layers = child->owner->owner->layers;
-				if (!((child->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0 &&
-				      (id_layers & state->layers) != 0))
-				{
-					/* Node does not need an update, so can;t continue with the
-					 * chain and need to switch to another one by leaving the
-					 * thread.
-					 */
-					break;
-				}
-				if ((rel->flag & DEPSREL_FLAG_CYCLIC) == 0) {
-					BLI_assert(child->num_links_pending > 0);
-					atomic_sub_and_fetch_uint32(&child->num_links_pending, 1);
-				}
-				if (child->num_links_pending == 0) {
-					bool is_scheduled = atomic_fetch_and_or_uint8(
-					        (uint8_t *)&child->scheduled, (uint8_t)true);
-					if (!is_scheduled) {
-						/* Node was not scheduled, switch to it! */
-						node = child;
-					}
-					else {
-						/* Someone else scheduled the node, leaving us
-						 * unemployed in this thread, we're leaving.
-						 */
-						break;
-					}
-				}
-				else {
-					/* There are other dependencies on the child, can't do
-					 * anything in the current thread.
-					 */
-					break;
-				}
-			}
-			else {
-				/* Happens when having cyclic dependencies.
-				 *
-				 * Nothing to do here, single child was already scheduled, we
-				 * can leave the thread now.
-				 */
-				break;
-			}
-		}
-		else {
-			/* TODO(sergey): It's possible to use one of the outgoing relations
-			 * as a chain which we'll try to keep alive, but it's a bit more
-			 * involved change.
-			 */
-			schedule_children(pool, state->graph, node, state->layers, thread_id);
-			break;
-		}
 	}
+
+	schedule_children(pool, state->graph, node, state->layers, thread_id);
 }
 
 typedef struct CalculatePengindData {
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index 7c6c25bef0..e10f86f6e9 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -180,6 +180,11 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
 			comp_node->done = 1;
 
 			/* Flush to nodes along links... */
+			/* TODO(sergey): This is mainly giving speedup due ot less queue pushes, which
+			 * reduces number of memory allocations.
+			 *
+			 * We should try solve the allocation issue instead of doing crazy things here.
+			 */
 			if (node->outlinks.size() == 1) {
 				OperationDepsNode *to_node = (OperationDepsNode *)node->outlinks[0]->to;
 				if (to_node->scheduled == false) {




More information about the Bf-blender-cvs mailing list