[FFmpeg-cvslog] avcodec/aarch64/me_cmp: add dotprod implementations of sse16 and vsse_intra16

Ramiro Polla git at videolan.org
Sat Aug 17 16:32:25 EEST 2024


ffmpeg | branch: master | Ramiro Polla <ramiro.polla at gmail.com> | Thu Aug 15 16:44:05 2024 +0200| [5c1c0325cd1bd3f826bbd73dffd0b07974a586bd] | committer: Ramiro Polla

avcodec/aarch64/me_cmp: add dotprod implementations of sse16 and vsse_intra16

checkasm --bench for Raspberry Pi 5 Model B Rev 1.0:
sse_0_c: 241.5
sse_0_neon: 37.2
sse_0_dotprod: 22.2
vsse_4_c: 148.7
vsse_4_neon: 31.0
vsse_4_dotprod: 15.7

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5c1c0325cd1bd3f826bbd73dffd0b07974a586bd
---

 libavcodec/aarch64/me_cmp_init_aarch64.c |  14 ++++
 libavcodec/aarch64/me_cmp_neon.S         | 114 +++++++++++++++++++++++++++++++
 2 files changed, 128 insertions(+)

diff --git a/libavcodec/aarch64/me_cmp_init_aarch64.c b/libavcodec/aarch64/me_cmp_init_aarch64.c
index 1e0f1cf4f1..fa2724403d 100644
--- a/libavcodec/aarch64/me_cmp_init_aarch64.c
+++ b/libavcodec/aarch64/me_cmp_init_aarch64.c
@@ -77,6 +77,13 @@ int vsse8_neon(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
 int vsse_intra8_neon(MpegEncContext *c, const uint8_t *s, const uint8_t *dummy,
                      ptrdiff_t stride, int h);
 
+#if HAVE_DOTPROD
+int sse16_neon_dotprod(MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2,
+                       ptrdiff_t stride, int h);
+int vsse_intra16_neon_dotprod(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
+                              ptrdiff_t stride, int h);
+#endif
+
 av_cold void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx)
 {
     int cpu_flags = av_get_cpu_flags();
@@ -113,6 +120,13 @@ av_cold void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx)
         c->median_sad[0] = pix_median_abs16_neon;
         c->median_sad[1] = pix_median_abs8_neon;
     }
+
+#if HAVE_DOTPROD
+    if (have_dotprod(cpu_flags)) {
+        c->sse[0] = sse16_neon_dotprod;
+        c->vsse[4] = vsse_intra16_neon_dotprod;
+    }
+#endif
 }
 
 int nsse16_neon_wrapper(MpegEncContext *c, const uint8_t *s1, const uint8_t *s2,
diff --git a/libavcodec/aarch64/me_cmp_neon.S b/libavcodec/aarch64/me_cmp_neon.S
index 7500c324bd..20e3b33a83 100644
--- a/libavcodec/aarch64/me_cmp_neon.S
+++ b/libavcodec/aarch64/me_cmp_neon.S
@@ -1559,3 +1559,117 @@ function pix_median_abs8_neon, export=1
         ret
 
 endfunc
+
+#if HAVE_DOTPROD
+ENABLE_DOTPROD
+
+function sse16_neon_dotprod, export=1
+        // x0 - unused
+        // x1 - pix1
+        // x2 - pix2
+        // x3 - stride
+        // w4 - h
+
+        cmp             w4, #4
+        movi            v17.4s, #0
+        b.lt            2f
+
+// Make 4 iterations at once
+1:
+
+        // res = abs(pix1[0] - pix2[0])
+        // res * res
+
+        ld1             {v0.16b}, [x1], x3              // Load pix1 vector for first iteration
+        ld1             {v1.16b}, [x2], x3              // Load pix2 vector for first iteration
+        ld1             {v2.16b}, [x1], x3              // Load pix1 vector for second iteration
+        uabd            v30.16b, v0.16b, v1.16b         // Absolute difference, first iteration
+        ld1             {v3.16b}, [x2], x3              // Load pix2 vector for second iteration
+        udot            v17.4s, v30.16b, v30.16b
+        uabd            v27.16b, v2.16b, v3.16b         // Absolute difference, second iteration
+        ld1             {v4.16b}, [x1], x3              // Load pix1 for third iteration
+        udot            v17.4s, v27.16b, v27.16b
+        ld1             {v5.16b}, [x2], x3              // Load pix2 for third iteration
+        uabd            v24.16b, v4.16b, v5.16b         // Absolute difference, third iteration
+        ld1             {v6.16b}, [x1], x3              // Load pix1 for fourth iteration
+        udot            v17.4s, v24.16b, v24.16b
+        ld1             {v7.16b}, [x2], x3              // Load pix2 for fouth iteration
+        uabd            v21.16b, v6.16b, v7.16b         // Absolute difference, fourth iteration
+        sub             w4, w4, #4                      // h -= 4
+        udot            v17.4s, v21.16b, v21.16b
+        cmp             w4, #4
+        b.ge            1b
+
+        cbz             w4, 3f
+
+// iterate by one
+2:
+
+        ld1             {v0.16b}, [x1], x3              // Load pix1
+        ld1             {v1.16b}, [x2], x3              // Load pix2
+
+        uabd            v30.16b, v0.16b, v1.16b
+        subs            w4, w4, #1
+        udot            v17.4s, v30.16b, v30.16b
+
+        b.ne            2b
+
+3:
+        uaddlv          d16, v17.4s                     // add up accumulator vector
+
+        fmov            w0, s16
+
+        ret
+endfunc
+
+function vsse_intra16_neon_dotprod, export=1
+        // x0           unused
+        // x1           uint8_t *pix1
+        // x2           uint8_t *dummy
+        // x3           ptrdiff_t stride
+        // w4           int h
+
+        ld1             {v0.16b}, [x1], x3
+        movi            v17.4s, #0
+
+        sub             w4, w4, #1 // we need to make h-1 iterations
+        cmp             w4, #3
+        b.lt            2f
+
+1:
+        // v = abs( pix1[0] - pix1[0 + stride] )
+        // score = sum( v * v )
+        ld1             {v1.16b}, [x1], x3
+        ld1             {v2.16b}, [x1], x3
+        uabd            v30.16b, v0.16b, v1.16b
+        ld1             {v3.16b}, [x1], x3
+        udot            v17.4s, v30.16b, v30.16b
+        uabd            v27.16b, v1.16b, v2.16b
+        udot            v17.4s, v27.16b, v27.16b
+        uabd            v25.16b, v2.16b, v3.16b
+        sub             w4, w4, #3
+        udot            v17.4s, v25.16b, v25.16b
+        cmp             w4, #3
+        mov             v0.16b, v3.16b
+
+        b.ge            1b
+        cbz             w4, 3f
+
+// iterate by one
+2:
+        ld1             {v1.16b}, [x1], x3
+        subs            w4, w4, #1
+        uabd            v30.16b, v0.16b, v1.16b
+        mov             v0.16b, v1.16b
+        udot            v17.4s, v30.16b, v30.16b
+        cbnz            w4, 2b
+
+3:
+        uaddlv          d17, v17.4s
+        fmov            w0, s17
+
+        ret
+endfunc
+
+DISABLE_DOTPROD
+#endif



More information about the ffmpeg-cvslog mailing list