i965/sched: Simplify work done by add_barrier_deps().
authorMatt Turner <mattst88@gmail.com>
Thu, 18 Aug 2016 23:47:05 +0000 (16:47 -0700)
committerMatt Turner <mattst88@gmail.com>
Fri, 19 Aug 2016 23:52:25 +0000 (16:52 -0700)
Scheduling barriers are implemented by placing a dependence on every
node before and after the barrier. This is unnecessary as we can limit
the number of nodes we place dependencies on to those between us and the
next barrier in each direction.

Runtime of dEQP-GLES31.functional.ssbo.layout.random.all_shared_buffer.23
is reduced from ~25 minutes to a little more than three.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94681
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp

index dfcaa80b58beccfba15ffcf3a3e10405ca82e647..a8987065f18b4b4e438704e446d4e854ea7cdf0d 100644 (file)
@@ -94,6 +94,8 @@ public:
     * successors is an exit node.
     */
    schedule_node *exit;
+
+   bool is_barrier;
 };
 
 /**
@@ -800,6 +802,7 @@ schedule_node::schedule_node(backend_instruction *inst,
    this->cand_generation = 0;
    this->delay = 0;
    this->exit = NULL;
+   this->is_barrier = false;
 
    /* We can't measure Gen6 timings directly but expect them to be much
     * closer to Gen7 than Gen4.
@@ -931,9 +934,13 @@ instruction_scheduler::add_barrier_deps(schedule_node *n)
    schedule_node *prev = (schedule_node *)n->prev;
    schedule_node *next = (schedule_node *)n->next;
 
+   n->is_barrier = true;
+
    if (prev) {
       while (!prev->is_head_sentinel()) {
          add_dep(prev, n, 0);
+         if (prev->is_barrier)
+            break;
          prev = (schedule_node *)prev->prev;
       }
    }
@@ -941,6 +948,8 @@ instruction_scheduler::add_barrier_deps(schedule_node *n)
    if (next) {
       while (!next->is_tail_sentinel()) {
          add_dep(n, next, 0);
+         if (next->is_barrier)
+            break;
          next = (schedule_node *)next->next;
       }
    }