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.
This commit is contained in:
parent
55c2cd85f0
commit
347410a322
@ -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);
|
||||
/* 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) {
|
||||
/* 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 {
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user