util/u_queue: add UTIL_QUEUE_INIT_SCALE_THREADS flag

This flag allow to create a single thread initially, but set
max_thread to the request thread count.

If the queue is full and num_threads is lower than max_threads,
we spawn a new thread to help process the queue faster.

This avoid creating N threads at queue creation time.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11296>
This commit is contained in:
Pierre-Eric Pelloux-Prayer 2021-06-09 13:49:23 +02:00
parent 0c88df1f6a
commit 3713dc6b2a
2 changed files with 11 additions and 3 deletions

View file

@ -441,7 +441,7 @@ util_queue_init(struct util_queue *queue,
queue->flags = flags; queue->flags = flags;
queue->max_threads = num_threads; queue->max_threads = num_threads;
queue->num_threads = num_threads; queue->num_threads = (flags & UTIL_QUEUE_INIT_SCALE_THREADS) ? 1 : num_threads;
queue->max_jobs = max_jobs; queue->max_jobs = max_jobs;
queue->global_data = global_data; queue->global_data = global_data;
@ -457,12 +457,12 @@ util_queue_init(struct util_queue *queue,
cnd_init(&queue->has_queued_cond); cnd_init(&queue->has_queued_cond);
cnd_init(&queue->has_space_cond); cnd_init(&queue->has_space_cond);
queue->threads = (thrd_t*) calloc(num_threads, sizeof(thrd_t)); queue->threads = (thrd_t*) calloc(queue->max_threads, sizeof(thrd_t));
if (!queue->threads) if (!queue->threads)
goto fail; goto fail;
/* start threads */ /* start threads */
for (i = 0; i < num_threads; i++) { for (i = 0; i < queue->num_threads; i++) {
if (!util_queue_create_thread(queue, i)) { if (!util_queue_create_thread(queue, i)) {
if (i == 0) { if (i == 0) {
/* no threads created, fail */ /* no threads created, fail */
@ -568,7 +568,14 @@ util_queue_add_job(struct util_queue *queue,
assert(queue->num_queued >= 0 && queue->num_queued <= queue->max_jobs); assert(queue->num_queued >= 0 && queue->num_queued <= queue->max_jobs);
if (queue->num_queued == queue->max_jobs) { if (queue->num_queued == queue->max_jobs) {
if ((queue->flags & UTIL_QUEUE_INIT_SCALE_THREADS) &&
execute != util_queue_finish_execute &&
queue->num_threads < queue->max_threads) {
util_queue_adjust_num_threads(queue, queue->num_threads + 1);
}
if (queue->flags & UTIL_QUEUE_INIT_RESIZE_IF_FULL && if (queue->flags & UTIL_QUEUE_INIT_RESIZE_IF_FULL &&
queue->total_jobs_size + job_size < S_256MB) { queue->total_jobs_size + job_size < S_256MB) {
/* If the queue is full, make it larger to avoid waiting for a free /* If the queue is full, make it larger to avoid waiting for a free

View file

@ -49,6 +49,7 @@ extern "C" {
#define UTIL_QUEUE_INIT_USE_MINIMUM_PRIORITY (1 << 0) #define UTIL_QUEUE_INIT_USE_MINIMUM_PRIORITY (1 << 0)
#define UTIL_QUEUE_INIT_RESIZE_IF_FULL (1 << 1) #define UTIL_QUEUE_INIT_RESIZE_IF_FULL (1 << 1)
#define UTIL_QUEUE_INIT_SET_FULL_THREAD_AFFINITY (1 << 2) #define UTIL_QUEUE_INIT_SET_FULL_THREAD_AFFINITY (1 << 2)
#define UTIL_QUEUE_INIT_SCALE_THREADS (1 << 3)
#if UTIL_FUTEX_SUPPORTED #if UTIL_FUTEX_SUPPORTED
#define UTIL_QUEUE_FENCE_FUTEX #define UTIL_QUEUE_FENCE_FUTEX