Mesa (master): st/mesa: pin driver threads to a fixed CCX when glthread is enabled
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Nov 21 02:19:19 UTC 2018
Module: Mesa
Branch: master
Commit: bc5adc27b5e52d27eca6a61ad1e049b160570c98
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=bc5adc27b5e52d27eca6a61ad1e049b160570c98
Author: Marek Olšák <marek.olsak at amd.com>
Date: Mon Nov 12 19:09:25 2018 -0500
st/mesa: pin driver threads to a fixed CCX when glthread is enabled
radeonsi has 3 driver threads (glthread, gallium, winsys), other drivers
may have 2 (glthread, gallium), so it makes sense to pin them to a random
CCX and keep that irrespective of the app thread.
Reviewed-by: Dave Airlie <airlied at redhat.com>
---
src/gallium/auxiliary/util/u_helpers.c | 63 +++++-----------------------------
src/gallium/auxiliary/util/u_helpers.h | 3 +-
src/mesa/state_tracker/st_manager.c | 11 ++++++
3 files changed, 21 insertions(+), 56 deletions(-)
diff --git a/src/gallium/auxiliary/util/u_helpers.c b/src/gallium/auxiliary/util/u_helpers.c
index 4c70c00417..821242c018 100644
--- a/src/gallium/auxiliary/util/u_helpers.c
+++ b/src/gallium/auxiliary/util/u_helpers.c
@@ -121,43 +121,6 @@ util_upload_index_buffer(struct pipe_context *pipe,
return *out_buffer != NULL;
}
-#ifdef HAVE_PTHREAD_SETAFFINITY
-
-static unsigned L3_cache_number;
-static once_flag thread_pinning_once_flag = ONCE_FLAG_INIT;
-
-static void
-util_set_full_cpu_affinity(void)
-{
- cpu_set_t cpuset;
-
- CPU_ZERO(&cpuset);
- for (unsigned i = 0; i < CPU_SETSIZE; i++)
- CPU_SET(i, &cpuset);
-
- pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset);
-}
-
-static void
-util_init_thread_pinning(void)
-{
- /* Get a semi-random number. */
- int64_t t = os_time_get_nano();
- L3_cache_number = (t ^ (t >> 8) ^ (t >> 16));
-
- /* Reset thread affinity for all child processes to prevent them from
- * inheriting the current thread's affinity.
- *
- * XXX: If the driver is unloaded after this, and the app later calls
- * fork(), the child process will likely crash before fork() returns,
- * because the address where util_set_full_cpu_affinity was located
- * will either be unmapped or point to random other contents.
- */
- pthread_atfork(NULL, NULL, util_set_full_cpu_affinity);
-}
-
-#endif
-
/**
* Called by MakeCurrent. Used to notify the driver that the application
* thread may have been changed.
@@ -170,30 +133,21 @@ util_init_thread_pinning(void)
* pinned.
*/
void
-util_context_thread_changed(struct pipe_context *ctx, thrd_t *upper_thread)
+util_pin_driver_threads_to_random_L3(struct pipe_context *ctx,
+ thrd_t *upper_thread)
{
-#ifdef HAVE_PTHREAD_SETAFFINITY
/* If pinning has no effect, don't do anything. */
if (util_cpu_caps.nr_cpus == util_cpu_caps.cores_per_L3)
return;
- thrd_t current = thrd_current();
- int cache = util_get_L3_for_pinned_thread(current,
- util_cpu_caps.cores_per_L3);
-
- call_once(&thread_pinning_once_flag, util_init_thread_pinning);
+ unsigned num_L3_caches = util_cpu_caps.nr_cpus /
+ util_cpu_caps.cores_per_L3;
- /* If the main thread is not pinned, choose the L3 cache. */
- if (cache == -1) {
- unsigned num_L3_caches = util_cpu_caps.nr_cpus /
- util_cpu_caps.cores_per_L3;
-
- /* Choose a different L3 cache for each subsequent MakeCurrent. */
- cache = p_atomic_inc_return(&L3_cache_number) % num_L3_caches;
- util_pin_thread_to_L3(current, cache, util_cpu_caps.cores_per_L3);
- }
+ /* Get a semi-random number. */
+ int64_t t = os_time_get_nano();
+ unsigned cache = (t ^ (t >> 8) ^ (t >> 16)) % num_L3_caches;
- /* Tell the driver to pin its threads to the same L3 cache. */
+ /* Tell the driver to pin its threads to the selected L3 cache. */
if (ctx->set_context_param) {
ctx->set_context_param(ctx, PIPE_CONTEXT_PARAM_PIN_THREADS_TO_L3_CACHE,
cache);
@@ -202,7 +156,6 @@ util_context_thread_changed(struct pipe_context *ctx, thrd_t *upper_thread)
/* Do the same for the upper level thread if there is any (e.g. glthread) */
if (upper_thread)
util_pin_thread_to_L3(*upper_thread, cache, util_cpu_caps.cores_per_L3);
-#endif
}
/* This is a helper for hardware bring-up. Don't remove. */
diff --git a/src/gallium/auxiliary/util/u_helpers.h b/src/gallium/auxiliary/util/u_helpers.h
index 38c47c1cc9..ed8467291b 100644
--- a/src/gallium/auxiliary/util/u_helpers.h
+++ b/src/gallium/auxiliary/util/u_helpers.h
@@ -52,7 +52,8 @@ bool util_upload_index_buffer(struct pipe_context *pipe,
unsigned *out_offset);
void
-util_context_thread_changed(struct pipe_context *ctx, thrd_t *upper_thread);
+util_pin_driver_threads_to_random_L3(struct pipe_context *ctx,
+ thrd_t *upper_thread);
struct pipe_query *
util_begin_pipestat_query(struct pipe_context *ctx);
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index 076ad42646..73729d7454 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -800,6 +800,17 @@ st_start_thread(struct st_context_iface *stctxi)
struct st_context *st = (struct st_context *) stctxi;
_mesa_glthread_init(st->ctx);
+
+ /* Pin all driver threads to one L3 cache for optimal performance
+ * on AMD Zen. This is only done if glthread is enabled.
+ *
+ * If glthread is disabled, st_draw.c re-pins driver threads regularly
+ * based on the location of the app thread.
+ */
+ struct glthread_state *glthread = st->ctx->GLThread;
+ if (glthread && st->pipe->set_context_param) {
+ util_pin_driver_threads_to_random_L3(st->pipe, &glthread->queue.threads[0]);
+ }
}
More information about the mesa-commit
mailing list