[opus] [RFC PATCH v1 1/2] Optimize repeated calls to opus_select_arch

Viswanath Puttagunta viswanath.puttagunta at linaro.org
Tue Jan 20 09:37:23 PST 2015


Currently, opus_select_arch() is being called during initial
setup of encoder/decoder structures and then stored. However,
this "arch" variable does not always get passed to every
function that may need it for architecture specific optimization.

As a result, when a certain function is to be optimized for
a particular architecture, we are having to change many function
signatures in the call stack to make this happen.

Instead, just optimize the opus_select_arch() such that only
the first call to it takes more time, but subsequent calls to
it are much faster.

This helps avoid needing to make too many changes to function
signatures.
---
 celt/arm/armcpu.c |   19 +++++++++++++++----
 celt/x86/x86cpu.c |   22 ++++++++++++++--------
 2 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/celt/arm/armcpu.c b/celt/arm/armcpu.c
index 1768525..26aae09 100644
--- a/celt/arm/armcpu.c
+++ b/celt/arm/armcpu.c
@@ -151,24 +151,35 @@ opus_uint32 opus_cpu_capabilities(void)
    "your platform.  Reconfigure with --disable-rtcd (or send patches)."
 #endif
 
-int opus_select_arch(void)
+static int detected = 0;
+static int arch_arm = 0;
+
+static int opus_select_arch_real(void)
 {
   opus_uint32 flags = opus_cpu_capabilities();
   int arch = 0;
 
   if(!(flags & OPUS_CPU_ARM_EDSP))
-    return arch;
+    goto final;
   arch++;
 
   if(!(flags & OPUS_CPU_ARM_MEDIA))
-    return arch;
+    goto final;
   arch++;
 
   if(!(flags & OPUS_CPU_ARM_NEON))
-    return arch;
+    goto final;
   arch++;
 
+final:
+  detected = 1;
+  arch_arm = arch;
   return arch;
 }
 
+int opus_select_arch(void)
+{
+   return (detected?arch_arm:opus_select_arch_real());
+}
+
 #endif
diff --git a/celt/x86/x86cpu.c b/celt/x86/x86cpu.c
index c82a4b7..ddf3cf3 100644
--- a/celt/x86/x86cpu.c
+++ b/celt/x86/x86cpu.c
@@ -87,7 +87,10 @@ static void opus_cpu_feature_check(CPU_Feature *cpu_feature)
     }
 }
 
-int opus_select_arch(void)
+static int detected = 0;
+static int arch_x86 = 0;
+
+static int opus_select_arch_real(void)
 {
     CPU_Feature cpu_feature = {0};
     int arch;
@@ -96,16 +99,19 @@ int opus_select_arch(void)
 
     arch = 0;
     if (!cpu_feature.HW_SSE2)
-    {
-       return arch;
-    }
+       goto final;
     arch++;
 
     if (!cpu_feature.HW_SSE41)
-    {
-        return arch;
-    }
+        goto final;
     arch++;
-
+final:
+    detected = 1;
+    arch_x86 = arch;
     return arch;
 }
+
+int opus_select_arch(void)
+{
+   return (detected?arch_x86:opus_select_arch_real());
+}
-- 
1.7.9.5



More information about the opus mailing list