[Bf-blender-cvs] [21350b7] master: Despgraph: Optimize cycles detection algorithm
Sergey Sharybin
noreply at git.blender.org
Mon Nov 7 11:44:12 CET 2016
Commit: 21350b73df0ebd78accf3567269e77d6dc774557
Author: Sergey Sharybin
Date: Fri Nov 4 17:45:14 2016 +0100
Branches: master
https://developer.blender.org/rB21350b73df0ebd78accf3567269e77d6dc774557
Despgraph: Optimize cycles detection algorithm
The idea is simple: when falling back to one of the nodes which was partially
handled we "resume" checking outgoing relations from the index which we stopped.
This gives about 15-20% depsgraph construction time save.
===================================================================
M source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
M source/blender/depsgraph/intern/depsgraph_build.cc
M source/blender/depsgraph/intern/nodes/deg_node.h
===================================================================
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
index 225cc64..d84a590 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
@@ -56,12 +56,14 @@ struct StackEntry {
void deg_graph_detect_cycles(Depsgraph *graph)
{
- /* Not is not visited at all during traversal. */
- const int NODE_NOT_VISITED = 0;
- /* Node has been visited during traversal and not in current stack. */
- const int NODE_VISITED = 1;
- /* Node has been visited during traversal and is in current stack. */
- const int NODE_IN_STACK = 2;
+ enum {
+ /* Not is not visited at all during traversal. */
+ NODE_NOT_VISITED = 0,
+ /* Node has been visited during traversal and not in current stack. */
+ NODE_VISITED = 1,
+ /* Node has been visited during traversal and is in current stack. */
+ NODE_IN_STACK = 2,
+ };
std::stack<StackEntry> traversal_stack;
foreach (OperationDepsNode *node, graph->operations) {
@@ -77,21 +79,23 @@ void deg_graph_detect_cycles(Depsgraph *graph)
entry.from = NULL;
entry.via_relation = NULL;
traversal_stack.push(entry);
- node->done = NODE_IN_STACK;
+ node->tag = NODE_IN_STACK;
}
else {
- node->done = NODE_NOT_VISITED;
+ node->tag = NODE_NOT_VISITED;
}
+ node->done = 0;
}
while (!traversal_stack.empty()) {
- StackEntry &entry = traversal_stack.top();
+ StackEntry entry = traversal_stack.top();
OperationDepsNode *node = entry.node;
bool all_child_traversed = true;
- foreach (DepsRelation *rel, node->outlinks) {
+ for (int i = node->done; i < node->outlinks.size(); ++i) {
+ DepsRelation *rel = node->outlinks[i];
if (rel->to->type == DEPSNODE_TYPE_OPERATION) {
OperationDepsNode *to = (OperationDepsNode *)rel->to;
- if (to->done == NODE_IN_STACK) {
+ if (to->tag == NODE_IN_STACK) {
printf("Dependency cycle detected:\n");
printf(" '%s' depends on '%s' through '%s'\n",
to->full_identifier().c_str(),
@@ -107,23 +111,24 @@ void deg_graph_detect_cycles(Depsgraph *graph)
current->via_relation->name);
current = current->from;
}
- /* TODO(sergey): So called roussian rlette cycle solver. */
+ /* TODO(sergey): So called russian roulette cycle solver. */
rel->flag |= DEPSREL_FLAG_CYCLIC;
}
- else if (to->done == NODE_NOT_VISITED) {
+ else if (to->tag == NODE_NOT_VISITED) {
StackEntry new_entry;
new_entry.node = to;
new_entry.from = &entry;
new_entry.via_relation = rel;
traversal_stack.push(new_entry);
- to->done = NODE_IN_STACK;
+ to->tag = NODE_IN_STACK;
all_child_traversed = false;
+ node->done = i;
break;
}
}
}
if (all_child_traversed) {
- node->done = NODE_VISITED;
+ node->tag = NODE_VISITED;
traversal_stack.pop();
}
}
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index 7b3922a..e21dac8 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -32,7 +32,7 @@
#include "MEM_guardedalloc.h"
-// #define DEBUG_TIME
+#define DEBUG_TIME
extern "C" {
#include "DNA_cachefile_types.h"
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h
index 810c6ee..7c2f538 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.h
+++ b/source/blender/depsgraph/intern/nodes/deg_node.h
@@ -80,8 +80,9 @@ struct DepsNode {
/* Nodes which depend on this one. */
Relations outlinks;
- /* Generic tag for traversal algorithms */
+ /* Generic tags for traversal algorithms. */
int done;
+ int tag;
/* Methods. */
More information about the Bf-blender-cvs
mailing list