[Mesa-dev] [PATCH] gallium/util: start with a random L3 cache index for AMD Zen

Marek Olšák maraeo at gmail.com
Fri Sep 7 20:12:24 UTC 2018


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/auxiliary/util/u_helpers.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_helpers.c b/src/gallium/auxiliary/util/u_helpers.c
index f773360adde..466add53fc9 100644
--- a/src/gallium/auxiliary/util/u_helpers.c
+++ b/src/gallium/auxiliary/util/u_helpers.c
@@ -23,20 +23,21 @@
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  **************************************************************************/
 
 #include "util/u_cpu_detect.h"
 #include "util/u_helpers.h"
 #include "util/u_inlines.h"
 #include "util/u_upload_mgr.h"
 #include "util/u_thread.h"
+#include "util/os_time.h"
 #include <inttypes.h>
 
 /**
  * This function is used to copy an array of pipe_vertex_buffer structures,
  * while properly referencing the pipe_vertex_buffer::buffer member.
  *
  * enabled_buffers is updated such that the bits corresponding to the indices
  * of disabled buffers are set to 0 and the enabled ones are set to 1.
  *
  * \sa util_copy_framebuffer_state
@@ -113,46 +114,57 @@ util_upload_index_buffer(struct pipe_context *pipe,
 
    u_upload_data(pipe->stream_uploader, start_offset,
                  info->count * info->index_size, 4,
                  (char*)info->index.user + start_offset,
                  out_offset, out_buffer);
    u_upload_unmap(pipe->stream_uploader);
    *out_offset -= start_offset;
    return *out_buffer != NULL;
 }
 
+static unsigned L3_cache_number;
+static once_flag init_cache_number_flag = ONCE_FLAG_INIT;
+
+static void
+util_init_cache_number(void)
+{
+   /* Get a semi-random number. */
+   int64_t t = os_time_get_nano();
+   L3_cache_number = (t ^ (t >> 8) ^ (t >> 16));
+}
+
 /**
  * Called by MakeCurrent. Used to notify the driver that the application
  * thread may have been changed.
  *
  * The function pins the current thread and driver threads to a group of
  * CPU cores that share the same L3 cache. This is needed for good multi-
  * threading performance on AMD Zen CPUs.
  *
  * \param upper_thread  thread in the state tracker that also needs to be
  *                      pinned.
  */
 void
 util_context_thread_changed(struct pipe_context *ctx, thrd_t *upper_thread)
 {
    thrd_t current = thrd_current();
    int cache = util_get_L3_for_pinned_thread(current,
                                              util_cpu_caps.cores_per_L3);
 
    /* If the main thread is not pinned, choose the L3 cache. */
    if (cache == -1) {
-      unsigned num_caches = util_cpu_caps.nr_cpus /
-                            util_cpu_caps.cores_per_L3;
-      static unsigned last_cache;
+      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(&last_cache) % num_caches;
+      call_once(&init_cache_number_flag, util_init_cache_number);
+      cache = p_atomic_inc_return(&L3_cache_number) % num_L3_caches;
       util_pin_thread_to_L3(current, cache, util_cpu_caps.cores_per_L3);
    }
 
    /* Tell the driver to pin its threads to the same L3 cache. */
    if (ctx->set_context_param) {
       ctx->set_context_param(ctx, PIPE_CONTEXT_PARAM_PIN_THREADS_TO_L3_CACHE,
                              cache);
    }
 
    /* Do the same for the upper level thread if there is any (e.g. glthread) */
-- 
2.17.1



More information about the mesa-dev mailing list