linux: use number of CPUs as automatic thread count
authorJanne Grunau <janne-libav@jannau.net>
Wed, 21 Dec 2011 00:18:01 +0000 (01:18 +0100)
committerJanne Grunau <janne-libav@jannau.net>
Thu, 22 Dec 2011 20:50:07 +0000 (21:50 +0100)
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
libavcodec/pthread.c

index 8e2e08b..b5ee3b5 100755 (executable)
--- 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
index ac15fef..1800f29 100644 (file)
  */
 
 #include "config.h"
+
+#if HAVE_SCHED_GETAFFINITY
+#define _GNU_SOURCE
+#include <sched.h>
+#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;