From ea4d5f48373ab856e01a3cf05426db6e823e01d1 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 21 Dec 2011 01:18:01 +0100 Subject: [PATCH] linux: use number of CPUs as automatic thread count Use sched_getaffinity to determine the number of logical CPUs. Limits the number of threads to 16 since slice threading of H.264 seems to be buggy with more than 16 threads. --- configure | 2 ++ libavcodec/pthread.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/configure b/configure index 8e2e08b95f..b5ee3b5bb2 100755 --- a/configure +++ b/configure @@ -1117,6 +1117,7 @@ HAVE_LIST=" posix_memalign round roundf + sched_getaffinity sdl sdl_video_size setmode @@ -2853,6 +2854,7 @@ check_func setrlimit check_func strerror_r check_func strptime check_func strtok_r +check_func sched_getaffinity check_func_headers io.h setmode check_func_headers lzo/lzo1x.h lzo1x_999_compress check_lib2 "windows.h psapi.h" GetProcessMemoryInfo -lpsapi diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index ac15fefd68..1800f291d7 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -30,6 +30,12 @@ */ #include "config.h" + +#if HAVE_SCHED_GETAFFINITY +#define _GNU_SOURCE +#include +#endif + #include "avcodec.h" #include "internal.h" #include "thread.h" @@ -133,6 +139,29 @@ typedef struct FrameThreadContext { int die; ///< Set when threads should exit. } FrameThreadContext; + +/* H264 slice threading seems to be buggy with more than 16 threads, + * limit the number of threads to 16 for automatic detection */ +#define MAX_AUTO_THREADS 16 + +static int get_logical_cpus(AVCodecContext *avctx) +{ + int ret, nb_cpus = 1; +#if HAVE_SCHED_GETAFFINITY + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + + ret = sched_getaffinity(0, sizeof(cpuset), &cpuset); + if (!ret) { + nb_cpus = CPU_COUNT(&cpuset); + } +#endif + av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus); + return FFMIN(nb_cpus, MAX_AUTO_THREADS); +} + + static void* attribute_align_arg worker(void *v) { AVCodecContext *avctx = v; @@ -237,6 +266,13 @@ static int thread_init(AVCodecContext *avctx) ThreadContext *c; int thread_count = avctx->thread_count; + if (!thread_count) { + int nb_cpus = get_logical_cpus(avctx); + // use number of cores + 1 as thread count if there is motre than one + if (nb_cpus > 1) + thread_count = avctx->thread_count = nb_cpus + 1; + } + if (thread_count <= 1) { avctx->active_thread_type = 0; return 0; @@ -697,6 +733,13 @@ static int frame_thread_init(AVCodecContext *avctx) FrameThreadContext *fctx; int i, err = 0; + if (!thread_count) { + int nb_cpus = get_logical_cpus(avctx); + // use number of cores + 1 as thread count if there is motre than one + if (nb_cpus > 1) + thread_count = avctx->thread_count = nb_cpus + 1; + } + if (thread_count <= 1) { avctx->active_thread_type = 0; return 0;