From 6cda08416b10e43b0a75b4d0a649f8bf29a24a8a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 15 Jul 2023 08:22:37 -0400 Subject: [PATCH] glthread: determine global locking once every 64 batches to fix get_time perf This mitigates a large perf degradation when the clock source is HPET instead of TSC. Just call get_time less frequently. Fixes: 3ed141e9 - glthread: add a heuristic to stop locking global mutexes with multiple contexts Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/8910 Acked-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/mesa/main/glthread.c | 29 +++++++++++++++++++++++------ src/mesa/main/glthread.h | 4 ++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/mesa/main/glthread.c b/src/mesa/main/glthread.c index a0d7cb6..fb153af 100644 --- a/src/mesa/main/glthread.c +++ b/src/mesa/main/glthread.c @@ -43,13 +43,8 @@ #include "state_tracker/st_context.h" static void -glthread_unmarshal_batch(void *job, void *gdata, int thread_index) +glthread_update_global_locking(struct gl_context *ctx) { - struct glthread_batch *batch = (struct glthread_batch*)job; - struct gl_context *ctx = batch->ctx; - unsigned pos = 0; - unsigned used = batch->used; - uint64_t *buffer = batch->buffer; struct gl_shared_state *shared = ctx->Shared; /* Determine if we should lock the global mutexes. */ @@ -102,12 +97,34 @@ glthread_unmarshal_batch(void *job, void *gdata, int thread_index) } simple_mtx_unlock(&shared->Mutex); + ctx->GLThread.LockGlobalMutexes = lock_mutexes; +} + +static void +glthread_unmarshal_batch(void *job, void *gdata, int thread_index) +{ + struct glthread_batch *batch = (struct glthread_batch*)job; + struct gl_context *ctx = batch->ctx; + unsigned pos = 0; + unsigned used = batch->used; + uint64_t *buffer = batch->buffer; + struct gl_shared_state *shared = ctx->Shared; + + /* Determine once every 64 batches whether shared mutexes should be locked. + * We have to do this less frequently because os_time_get_nano() is very + * expensive if the clock source is not TSC. See: + * https://gitlab.freedesktop.org/mesa/mesa/-/issues/8910 + */ + if (ctx->GLThread.GlobalLockUpdateBatchCounter++ % 64 == 0) + glthread_update_global_locking(ctx); + /* Execute the GL calls. */ _glapi_set_dispatch(ctx->Dispatch.Current); /* Here we lock the mutexes once globally if possible. If not, we just * fallback to the individual API calls doing it. */ + bool lock_mutexes = ctx->GLThread.LockGlobalMutexes; if (lock_mutexes) { _mesa_HashLockMutex(shared->BufferObjects); ctx->BufferObjectsLocked = true; diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h index 8fc35f3..773c2f6 100644 --- a/src/mesa/main/glthread.h +++ b/src/mesa/main/glthread.h @@ -273,6 +273,10 @@ struct glthread_state /** The last added call of the given function. */ struct marshal_cmd_CallList *LastCallList; struct marshal_cmd_BindBuffer *LastBindBuffer; + + /** Global mutex update info. */ + unsigned GlobalLockUpdateBatchCounter; + bool LockGlobalMutexes; }; void _mesa_glthread_init(struct gl_context *ctx); -- 2.7.4