diff mbox series

[FFmpeg-devel,1/7] lavu/cpu: add av_cpu_job_count()

Message ID 20220920175021.60790-2-rcombs@rcombs.me
State New
Headers show
Series [FFmpeg-devel,1/7] lavu/cpu: add av_cpu_job_count() | expand

Checks

Context Check Description
yinshiyou/commit_msg_loongarch64 warning Please wrap lines in the body of the commit message between 60 and 72 characters.
yinshiyou/make_fate_loongarch64 success Make fate finished
yinshiyou/make_loongarch64 warning New warnings during build
andriy/commit_msg_x86 warning Please wrap lines in the body of the commit message between 60 and 72 characters.
andriy/configure_x86 warning Failed to run configure

Commit Message

rcombs Sept. 20, 2022, 5:50 p.m. UTC
This estimates an appropriate number of jobs for a task to be broken up into.
This may be higher than the core count in a heterogeneous system.

Currently implemented only on Apple platforms; otherwise, we assume homogeneity.
---
 doc/APIchanges      |  3 +++
 libavutil/cpu.c     | 37 +++++++++++++++++++++++++++++++++++++
 libavutil/cpu.h     | 11 +++++++++++
 libavutil/version.h |  4 ++--
 4 files changed, 53 insertions(+), 2 deletions(-)

Comments

Anton Khirnov Sept. 22, 2022, 1:49 p.m. UTC | #1
It is very nonobvious to me that it makes sense to define a global job
count that is independent of the task at hand.

And we could really do with fewer global variables, not more.
Ronald S. Bultje Sept. 22, 2022, 2:56 p.m. UTC | #2
Hi,

On Thu, Sep 22, 2022 at 9:49 AM Anton Khirnov <anton@khirnov.net> wrote:

> It is very nonobvious to me that it makes sense to define a global job
> count that is independent of the task at hand.
>

I agree with Anton here. This is very heuristical and dependent on the type
of job. This therefore belongs as an implementation detail where it is
used, not as a global public API.

Ronald
diff mbox series

Patch

diff --git a/doc/APIchanges b/doc/APIchanges
index 729f56be7b..6059b495dd 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,9 @@  libavutil:     2021-04-27
 
 API changes, most recent first:
 
+2022-09-20 - xxxxxxxxxx - lavu 57.37.100 - cpu.h
+  Add av_cpu_job_count() and av_cpu_force_job_count().
+
 2022-09-03 - xxxxxxxxxx - lavu 57.36.100 - pixfmt.h
   Add AV_PIX_FMT_P012, AV_PIX_FMT_Y212, AV_PIX_FMT_XV30, AV_PIX_FMT_XV36
 
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 0035e927a5..b846a4a2d5 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -51,6 +51,7 @@ 
 
 static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1);
 static atomic_int cpu_count = ATOMIC_VAR_INIT(-1);
+static atomic_int job_count = ATOMIC_VAR_INIT(-1);
 
 static int get_cpu_flags(void)
 {
@@ -251,6 +252,42 @@  void av_cpu_force_count(int count)
     atomic_store_explicit(&cpu_count, count, memory_order_relaxed);
 }
 
+int av_cpu_job_count(void)
+{
+    static atomic_int printed = ATOMIC_VAR_INIT(0);
+    int loaded = 0;
+
+    int jobs = av_cpu_count();
+
+#if __APPLE__
+    int nperflevels = 1;
+    size_t len = sizeof(nperflevels);
+
+    if (sysctlbyname("hw.nperflevels", &nperflevels, &len, NULL, 0) == -1)
+        nperflevels = 1;
+
+    if (nperflevels > 1)
+        jobs *= 3;
+#endif
+
+    if (!atomic_exchange_explicit(&printed, 1, memory_order_relaxed))
+        av_log(NULL, AV_LOG_DEBUG, "computed default job factor of %d\n", jobs);
+
+    loaded = atomic_load_explicit(&job_count, memory_order_relaxed);
+
+    if (loaded > 0) {
+        jobs = loaded;
+        av_log(NULL, AV_LOG_DEBUG, "overriding to job factor of %d\n", jobs);
+    }
+
+    return jobs;
+}
+
+void av_cpu_force_job_count(int factor)
+{
+    atomic_store_explicit(&job_count, factor, memory_order_relaxed);
+}
+
 size_t av_cpu_max_align(void)
 {
 #if ARCH_MIPS
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 9711e574c5..20f037afe1 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -110,6 +110,17 @@  int av_cpu_count(void);
  */
 void av_cpu_force_count(int count);
 
+/**
+ * @return an estimated optimal maximum number of jobs for tasks to be sliced into.
+ */
+int av_cpu_job_count(void);
+
+/**
+ * Overrides job count computation and forces the specified count.
+ * Count < 1 disables forcing of specific count.
+ */
+void av_cpu_force_job_count(int count);
+
 /**
  * Get the maximum data alignment that may be required by FFmpeg.
  *
diff --git a/libavutil/version.h b/libavutil/version.h
index 0585fa7b80..9c44cef6aa 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,8 +79,8 @@ 
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  57
-#define LIBAVUTIL_VERSION_MINOR  36
-#define LIBAVUTIL_VERSION_MICRO 102
+#define LIBAVUTIL_VERSION_MINOR  37
+#define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                                LIBAVUTIL_VERSION_MINOR, \