st/mesa: regularly re-pin driver threads to the CCX where the app thread is
authorMarek Olšák <marek.olsak@amd.com>
Mon, 12 Nov 2018 23:10:59 +0000 (18:10 -0500)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 21 Nov 2018 02:18:30 +0000 (21:18 -0500)
This is used when glthread is disabled.

Mesa pretty much chases the app thread on the CPU.
The performance is the same as pinning the app thread.

Reviewed-by: Dave Airlie <airlied@redhat.com>
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_draw.c

index 14b9b018809f8821394a6288164504a776b7917f..95133c7020f35d777bb30a84e2cd692509ba5763 100644 (file)
@@ -193,6 +193,8 @@ struct st_context
    /** This masks out unused shader resources. Only valid in draw calls. */
    uint64_t active_states;
 
+   unsigned pin_thread_counter; /* for L3 thread pinning on AMD Zen */
+
    /* If true, further analysis of states is required to know if something
     * has changed. Used mainly for shaders.
     */
index eb52d9505b68fc58910478608f0256151cc11a8c..5910ffa5bdaeb92e48e36e2ab8d6812c91f1a0ec 100644 (file)
@@ -58,6 +58,7 @@
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
+#include "util/u_cpu_detect.h"
 #include "util/u_inlines.h"
 #include "util/u_format.h"
 #include "util/u_prim.h"
 #include "draw/draw_context.h"
 #include "cso_cache/cso_context.h"
 
+#ifdef PIPE_OS_LINUX
+#include <sched.h>
+#define HAVE_SCHED_GETCPU 1
+#else
+#define sched_getcpu() 0
+#define HAVE_SCHED_GETCPU 0
+#endif
 
 /**
  * Set the restart index.
@@ -122,6 +130,30 @@ prepare_draw(struct st_context *st, struct gl_context *ctx)
        st->gfx_shaders_may_be_dirty) {
       st_validate_state(st, ST_PIPELINE_RENDER);
    }
+
+   struct pipe_context *pipe = st->pipe;
+
+   /* Pin threads regularly to the same Zen CCX that the main thread is
+    * running on. The main thread can move between CCXs.
+    */
+   if (unlikely(HAVE_SCHED_GETCPU && /* Linux */
+                /* AMD Zen */
+                util_cpu_caps.nr_cpus != util_cpu_caps.cores_per_L3 &&
+                /* no glthread */
+                ctx->CurrentClientDispatch != ctx->MarshalExec &&
+                /* driver support */
+                pipe->set_context_param &&
+                /* do it occasionally */
+                ++st->pin_thread_counter % 512 == 0)) {
+      int cpu = sched_getcpu();
+      if (cpu >= 0) {
+         unsigned L3_cache = cpu / util_cpu_caps.cores_per_L3;
+
+         pipe->set_context_param(pipe,
+                                 PIPE_CONTEXT_PARAM_PIN_THREADS_TO_L3_CACHE,
+                                 L3_cache);
+      }
+   }
 }
 
 /**