diff options
author | Muhammad Faiz <mfcc64@gmail.com> | 2017-07-12 03:16:33 +0300 |
---|---|---|
committer | Muhammad Faiz <mfcc64@gmail.com> | 2017-07-19 11:51:38 +0300 |
commit | 22b72de04bfd0aa9f00546f10b20615120c0d9c6 (patch) | |
tree | dab4276cadd12afd2902996a321d0c829861e20a | |
parent | b505f15b1530d72682b3314e84936f80fe6e43b2 (diff) |
avfilter/pthread: use slice threading from avutil
Benchmark (with 2 cpus):
./ffmpeg -f rawvideo -s 1280x720 -t 1000 -i /dev/zero \
-filter_threads $threads -vf transpose=clock -f null null
threads=2:
old: 31.129s 31.446s 31.574s
new: 29.602s 29.636s 29.656s
threads=3 (nb_threads = nb_cpus + 1 is bad choice at this situation):
old: 40.132s 40.279s 40.279s
new: 39.308s 39.570s 39.693s
threads=4:
old: 31.306s 31.366s 31.654s
new: 30.231s 30.360s 30.451s
Signed-off-by: Muhammad Faiz <mfcc64@gmail.com>
-rw-r--r-- | libavfilter/pthread.c | 128 |
1 files changed, 12 insertions, 116 deletions
diff --git a/libavfilter/pthread.c b/libavfilter/pthread.c index c7a00210d6..567dd4c178 100644 --- a/libavfilter/pthread.c +++ b/libavfilter/pthread.c @@ -27,6 +27,7 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/thread.h" +#include "libavutil/slicethread.h" #include "avfilter.h" #include "internal.h" @@ -34,85 +35,26 @@ typedef struct ThreadContext { AVFilterGraph *graph; - - int nb_threads; - pthread_t *workers; + AVSliceThread *thread; avfilter_action_func *func; /* per-execute parameters */ AVFilterContext *ctx; void *arg; int *rets; - int nb_jobs; - - pthread_cond_t last_job_cond; - pthread_cond_t current_job_cond; - pthread_mutex_t current_job_lock; - int current_job; - unsigned int current_execute; - int done; } ThreadContext; -static void* attribute_align_arg worker(void *v) +static void worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads) { - ThreadContext *c = v; - int our_job = c->nb_jobs; - int nb_threads = c->nb_threads; - unsigned int last_execute = 0; - int ret, self_id; - - pthread_mutex_lock(&c->current_job_lock); - self_id = c->current_job++; - - for (;;) { - while (our_job >= c->nb_jobs) { - if (c->current_job == nb_threads + c->nb_jobs) - pthread_cond_signal(&c->last_job_cond); - - while (last_execute == c->current_execute && !c->done) - pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); - last_execute = c->current_execute; - our_job = self_id; - - if (c->done) { - pthread_mutex_unlock(&c->current_job_lock); - return NULL; - } - } - pthread_mutex_unlock(&c->current_job_lock); - - ret = c->func(c->ctx, c->arg, our_job, c->nb_jobs); - if (c->rets) - c->rets[our_job % c->nb_jobs] = ret; - - pthread_mutex_lock(&c->current_job_lock); - our_job = c->current_job++; - } + ThreadContext *c = priv; + int ret = c->func(c->ctx, c->arg, jobnr, nb_jobs); + if (c->rets) + c->rets[jobnr] = ret; } static void slice_thread_uninit(ThreadContext *c) { - int i; - - pthread_mutex_lock(&c->current_job_lock); - c->done = 1; - pthread_cond_broadcast(&c->current_job_cond); - pthread_mutex_unlock(&c->current_job_lock); - - for (i = 0; i < c->nb_threads; i++) - pthread_join(c->workers[i], NULL); - - pthread_mutex_destroy(&c->current_job_lock); - pthread_cond_destroy(&c->current_job_cond); - pthread_cond_destroy(&c->last_job_cond); - av_freep(&c->workers); -} - -static void slice_thread_park_workers(ThreadContext *c) -{ - while (c->current_job != c->nb_threads + c->nb_jobs) - pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); - pthread_mutex_unlock(&c->current_job_lock); + avpriv_slicethread_free(&c->thread); } static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func, @@ -122,67 +64,21 @@ static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func, if (nb_jobs <= 0) return 0; - - pthread_mutex_lock(&c->current_job_lock); - - c->current_job = c->nb_threads; - c->nb_jobs = nb_jobs; c->ctx = ctx; c->arg = arg; c->func = func; c->rets = ret; - c->current_execute++; - - pthread_cond_broadcast(&c->current_job_cond); - - slice_thread_park_workers(c); + avpriv_slicethread_execute(c->thread, nb_jobs, 0); return 0; } static int thread_init_internal(ThreadContext *c, int nb_threads) { - int i, ret; - - if (!nb_threads) { - int nb_cpus = av_cpu_count(); - // use number of cores + 1 as thread count if there is more than one - if (nb_cpus > 1) - nb_threads = nb_cpus + 1; - else - nb_threads = 1; - } - + nb_threads = avpriv_slicethread_create(&c->thread, c, worker_func, NULL, nb_threads); if (nb_threads <= 1) - return 1; - - c->nb_threads = nb_threads; - c->workers = av_mallocz_array(sizeof(*c->workers), nb_threads); - if (!c->workers) - return AVERROR(ENOMEM); - - c->current_job = 0; - c->nb_jobs = 0; - c->done = 0; - - pthread_cond_init(&c->current_job_cond, NULL); - pthread_cond_init(&c->last_job_cond, NULL); - - pthread_mutex_init(&c->current_job_lock, NULL); - pthread_mutex_lock(&c->current_job_lock); - for (i = 0; i < nb_threads; i++) { - ret = pthread_create(&c->workers[i], NULL, worker, c); - if (ret) { - pthread_mutex_unlock(&c->current_job_lock); - c->nb_threads = i; - slice_thread_uninit(c); - return AVERROR(ret); - } - } - - slice_thread_park_workers(c); - - return c->nb_threads; + avpriv_slicethread_free(&c->thread); + return FFMAX(nb_threads, 1); } int ff_graph_thread_init(AVFilterGraph *graph) |