[FFmpeg-devel] [PATCHv2 2/2] lavc/flacdsp: optimise RVV vector type for lpc16

Rémi Denis-Courmont remi at remlab.net
Wed May 15 20:47:12 EEST 2024


This calculates the optimal vector type value at run-time based on the
hardware vector length and the FLAC LPC prediction order. In this
particular case, the additional computation is easily amortised over
the loop iterations:

T-Head C908:
    C     V before  V after
 1   48.0    214.7     95.2
 2   64.7    214.2     94.7
 3   79.7    213.5     94.5
 4   96.2    196.5     94.2 #
 5  111.0    195.7    118.5
 6  127.0    211.2    102.0
 7  143.7    194.2    101.5
 8  175.7    193.2    101.2 #
 9  176.2    224.2    126.0
10  191.5    192.0    125.5
11  224.5    191.2    124.7
12  223.0    190.2    124.2
13  239.2    189.5    123.7
14  253.7    188.7    139.5
15  286.2    188.0    122.7
16  284.0    187.0    122.5 #
17  300.2    186.5    186.5
18  314.0    185.5    185.7
19  329.7    184.7    185.0
20  343.0    184.2    184.2
21  358.7    199.2    183.7
22  371.7    182.7    182.7
23  387.5    181.7    182.0
24  400.7    181.0    181.2
25  431.5    180.2    196.5
26  443.7    195.5    196.0
27  459.0    178.7    196.2
28  470.7    177.7    194.2
29  470.0    177.0    193.5
30  481.2    176.2    176.5
31  496.2    175.5    175.7
32  507.2    174.7    191.0 #

 # Power of two boundary.

With 128-bit vectors, improvements are expected for the first two
test cases only. For the other two, there is overhead but below noise.
Improvements should be better observable with prediction order of 8
and less, or on hardware with larger vector sizes.

The same optimisation strategy should be applicable to LPC32
(and work-in-progress LPC33), but is left as a future exercise.
---
 libavcodec/riscv/flacdsp_init.c |  2 +-
 libavcodec/riscv/flacdsp_rvv.S  | 12 ++++++++++--
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/libavcodec/riscv/flacdsp_init.c b/libavcodec/riscv/flacdsp_init.c
index 4f1652dbe7..735aec0691 100644
--- a/libavcodec/riscv/flacdsp_init.c
+++ b/libavcodec/riscv/flacdsp_init.c
@@ -71,7 +71,7 @@ av_cold void ff_flacdsp_init_riscv(FLACDSPContext *c, enum AVSampleFormat fmt,
     if ((flags & AV_CPU_FLAG_RVV_I32) && (flags & AV_CPU_FLAG_RVB_ADDR)) {
         int vlenb = ff_get_rv_vlenb();
 
-        if (vlenb >= 16)
+        if ((flags & AV_CPU_FLAG_RVB_BASIC) && vlenb >= 16)
             c->lpc16 = ff_flac_lpc16_rvv;
 
 # if (__riscv_xlen >= 64)
diff --git a/libavcodec/riscv/flacdsp_rvv.S b/libavcodec/riscv/flacdsp_rvv.S
index 6287faa260..45608dfd47 100644
--- a/libavcodec/riscv/flacdsp_rvv.S
+++ b/libavcodec/riscv/flacdsp_rvv.S
@@ -20,8 +20,16 @@
 
 #include "libavutil/riscv/asm.S"
 
-func ff_flac_lpc16_rvv, zve32x
-        vsetvli zero, a2, e32, m8, ta, ma
+func ff_flac_lpc16_rvv, zve32x, zbb
+        csrr    t0, vlenb
+        addi    t2, a2, -1
+        clz     t0, t0
+        clz     t2, t2
+        addi    t0, t0, VTYPE_E32 | VTYPE_M8 | VTYPE_TA | VTYPE_MA
+        li      t1, VTYPE_E32 | VTYPE_M1 | VTYPE_TA | VTYPE_MA
+        sub     t0, t0, t2 // t0 += log2(next_power_of_two(len) / vlenb) + 1
+        max     t0, t0, t1
+        vsetvl  zero, a2, t0
         vle32.v v8, (a1)
         sub     a4, a4, a2
         vle32.v v16, (a0)
-- 
2.43.0



More information about the ffmpeg-devel mailing list