PR #25558 opened by sebokgyul
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25558
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25558.patch

The original implementation was slower than C on all tested cores.

The new version computes 8 outputs per iteration. The caller always
passes even start and end, which the x86 version also relies on, so
the tail only handles 4 and 2 outputs.

checkasm --bench (cycles, median of 7 runs). A55/A76/X1: Pixel 6a,
A510/A710/X2: Vivo Pad 2.

```
clang         c   neon_original      neon_new
A55         900    2303 (0.39x)   576 (1.56x)
A76         302     550 (0.55x)   204 (1.48x)
X1          173     322 (0.54x)   109 (1.59x)
A510        952    2398 (0.40x)   459 (2.07x)
A710        262     498 (0.53x)   194 (1.35x)
X2          169     298 (0.57x)   106 (1.58x)

gcc           c   neon_original      neon_new
A55         990    2301 (0.43x)   575 (1.72x)
A76         382     549 (0.69x)   205 (1.87x)
X1          208     322 (0.65x)   108 (1.91x)
A510        971    2395 (0.41x)   449 (2.16x)
A710        338     498 (0.68x)   194 (1.74x)
X2          202     298 (0.68x)   107 (1.89x)
```

5.1 HE-AAC decoding with -threads 1 is about 1-2.5% faster.

Tested with checkasm (qemu and the six cores above) and fate-aac under qemu.


>From 435a89a470babf8d54208265704ff18d8d9e5001 Mon Sep 17 00:00:00 2001
From: Gyula Sebok <[email protected]>
Date: Wed, 28 Oct 2026 04:41:02 +0100
Subject: [PATCH] aarch64/sbrdsp: rewrite hf_gen to remove faddp reduction

The original implementation was slower than C on all tested cores.

The new version computes 8 outputs per iteration. The caller always
passes even start and end, which the x86 version also relies on, so
the tail only handles 4 and 2 outputs.

checkasm --bench (cycles, median of 7 runs). A55/A76/X1: Pixel 6a,
A510/A710/X2: Vivo Pad 2.

clang         c   neon_original      neon_new
A55         900    2303 (0.39x)   576 (1.56x)
A76         302     550 (0.55x)   204 (1.48x)
X1          173     322 (0.54x)   109 (1.59x)
A510        952    2398 (0.40x)   459 (2.07x)
A710        262     498 (0.53x)   194 (1.35x)
X2          169     298 (0.57x)   106 (1.58x)

gcc           c   neon_original      neon_new
A55         990    2301 (0.43x)   575 (1.72x)
A76         382     549 (0.69x)   205 (1.87x)
X1          208     322 (0.65x)   108 (1.91x)
A510        971    2395 (0.41x)   449 (2.16x)
A710        338     498 (0.68x)   194 (1.74x)
X2          202     298 (0.68x)   107 (1.89x)

5.1 HE-AAC decoding with -threads 1 is about 1-2.5% faster.

Signed-off-by: Gyula Sebok <[email protected]>
---
 libavcodec/aarch64/sbrdsp_neon.S | 98 +++++++++++++++++++++++---------
 1 file changed, 72 insertions(+), 26 deletions(-)

diff --git a/libavcodec/aarch64/sbrdsp_neon.S b/libavcodec/aarch64/sbrdsp_neon.S
index d3639417173..c4b8dd07d00 100644
--- a/libavcodec/aarch64/sbrdsp_neon.S
+++ b/libavcodec/aarch64/sbrdsp_neon.S
@@ -200,37 +200,83 @@ endfunc
 function ff_sbr_hf_gen_neon, export=1
         sxtw            x4, w4
         sxtw            x5, w5
+        ld1             {v1.2s}, [x3]
+        ld1             {v2.2s}, [x2]
         movrel          x6, factors
         ld1             {v7.4s}, [x6]
-        dup             v1.4s, v0.s[0]
-        mov             v2.8b, v1.8b
-        mov             v2.s[2], v7.s[0]
-        mov             v2.s[3], v7.s[0]
-        fmul            v1.4s, v1.4s, v2.4s
-        ld1             {v0.d}[0], [x3]
-        ld1             {v0.d}[1], [x2]
-        fmul            v0.4s, v0.4s, v1.4s
-        fmul            v1.4s, v0.4s, v7.4s
-        rev64           v0.4s, v0.4s
+        fmul            v1.2s, v1.2s, v0.s[0]
+        fmul            v2.2s, v2.2s, v0.s[0]           // a2, a3
+        fmul            v1.2s, v1.2s, v0.s[0]           // a0, a1
+        fmul            v4.4s, v7.4s, v1.s[1]           // a1, -a1, a1, -a1
+        fmul            v5.4s, v7.4s, v2.s[1]           // a3, -a3, a3, -a3
         sub             x7, x5, x4
+        subs            x7, x7, #8
         add             x0, x0, x4, lsl #3
         add             x1, x1, x4, lsl #3
-        sub             x1, x1, #16
-1:      ld1             {v2.4s}, [x1], #16
-        ld1             {v3.2s}, [x1]
-        fmul            v4.4s, v2.4s, v1.4s
-        fmul            v5.4s, v2.4s, v0.4s
-        faddp           v4.4s, v4.4s, v4.4s
-        faddp           v5.4s, v5.4s, v5.4s
-        faddp           v4.4s, v4.4s, v4.4s
-        faddp           v5.4s, v5.4s, v5.4s
-        mov             v4.s[1], v5.s[0]
-        fadd            v4.2s, v4.2s, v3.2s
-        st1             {v4.2s}, [x0], #8
-        sub             x1, x1, #8
-        subs            x7, x7, #1
-        b.gt            1b
-        ret
+        b.lt            2f
+1:      ldr             q16, [x1, #-16]                 // X_low[i-2], 
X_low[i-1]
+        ld1             {v18.4s, v19.4s, v20.4s, v21.4s}, [x1], #64 // 
X_low[i] .. X_low[i+7]
+        subs            x7, x7, #8
+        ext             v22.16b, v16.16b, v18.16b, #8   // X_low[i-1], X_low[i]
+        ext             v23.16b, v18.16b, v19.16b, #8
+        ext             v24.16b, v19.16b, v20.16b, #8
+        ext             v25.16b, v20.16b, v21.16b, #8
+        rev64           v17.4s, v16.4s                  // swap re/im
+        rev64           v26.4s, v18.4s
+        rev64           v27.4s, v19.4s
+        rev64           v28.4s, v20.4s
+        rev64           v29.4s, v22.4s
+        rev64           v30.4s, v23.4s
+        rev64           v31.4s, v24.4s
+        rev64           v3.4s,  v25.4s
+        fmla            v21.4s, v20.4s, v1.s[0]
+        fmla            v20.4s, v19.4s, v1.s[0]
+        fmla            v19.4s, v18.4s, v1.s[0]
+        fmla            v18.4s, v16.4s, v1.s[0]
+        fmls            v21.4s, v28.4s, v4.4s
+        fmls            v20.4s, v27.4s, v4.4s
+        fmls            v19.4s, v26.4s, v4.4s
+        fmls            v18.4s, v17.4s, v4.4s
+        fmla            v21.4s, v25.4s, v2.s[0]
+        fmla            v20.4s, v24.4s, v2.s[0]
+        fmla            v19.4s, v23.4s, v2.s[0]
+        fmla            v18.4s, v22.4s, v2.s[0]
+        fmls            v21.4s, v3.4s,  v5.4s
+        fmls            v20.4s, v31.4s, v5.4s
+        fmls            v19.4s, v30.4s, v5.4s
+        fmls            v18.4s, v29.4s, v5.4s
+        st1             {v18.4s, v19.4s, v20.4s, v21.4s}, [x0], #64
+        b.ge            1b
+2:      tbz             w7, #2, 3f                      // 4 outputs left?
+        ldr             q16, [x1, #-16]
+        ld1             {v18.4s, v19.4s}, [x1], #32
+        ext             v22.16b, v16.16b, v18.16b, #8
+        ext             v24.16b, v18.16b, v19.16b, #8
+        rev64           v17.4s, v16.4s
+        rev64           v20.4s, v18.4s
+        rev64           v23.4s, v22.4s
+        rev64           v25.4s, v24.4s
+        fmla            v19.4s, v18.4s, v1.s[0]
+        fmla            v18.4s, v16.4s, v1.s[0]
+        fmls            v19.4s, v20.4s, v4.4s
+        fmls            v18.4s, v17.4s, v4.4s
+        fmla            v19.4s, v24.4s, v2.s[0]
+        fmla            v18.4s, v22.4s, v2.s[0]
+        fmls            v19.4s, v25.4s, v5.4s
+        fmls            v18.4s, v23.4s, v5.4s
+        st1             {v18.4s, v19.4s}, [x0], #32
+3:      tbz             w7, #1, 4f                      // 2 outputs left?
+        ldr             q16, [x1, #-16]
+        ld1             {v18.4s}, [x1]
+        ext             v22.16b, v16.16b, v18.16b, #8
+        rev64           v17.4s, v16.4s
+        rev64           v23.4s, v22.4s
+        fmla            v18.4s, v16.4s, v1.s[0]
+        fmls            v18.4s, v17.4s, v4.4s
+        fmla            v18.4s, v22.4s, v2.s[0]
+        fmls            v18.4s, v23.4s, v5.4s
+        st1             {v18.4s}, [x0]
+4:      ret
 endfunc
 
 function ff_sbr_hf_g_filt_neon, export=1
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to