ipred_dc/dc_left/dc_top/dc_128 implementation in RISC-V assembly

Results on Spacemit K1:

Benchmark results:
  name                                ticks +/- stddev         time (nanoseconds) (vs ref)
  nop:                                 12.1 +/- 0.5             6.2 ns +/- 0.4
  intra_pred_dc_128_w4_8bpc_c:         41.0 +/- 8.8            20.9 ns +/- 4.7
  intra_pred_dc_128_w4_8bpc_rvv:       31.6 +/- 7.8            16.1 ns +/- 4.1    ( 1.17x)
  intra_pred_dc_128_w4_16bpc_c:        90.1 +/- 13.9           46.0 ns +/- 7.7
  intra_pred_dc_128_w8_8bpc_c:         77.1 +/- 10.7           39.4 ns +/- 6.0
  intra_pred_dc_128_w8_8bpc_rvv:       42.0 +/- 7.7            21.5 ns +/- 4.2    ( 1.73x)
  intra_pred_dc_128_w8_16bpc_c:       200.2 +/- 18.8          102.3 ns +/- 11.4
  intra_pred_dc_128_w16_8bpc_c:       170.7 +/- 15.8           87.2 ns +/- 9.6
  intra_pred_dc_128_w16_8bpc_rvv:      58.3 +/- 8.3            29.8 ns +/- 4.6    ( 2.82x)
  intra_pred_dc_128_w16_16bpc_c:      468.1 +/- 28.8          239.1 ns +/- 20.3
  intra_pred_dc_128_w32_8bpc_c:       397.1 +/- 31.8          202.9 ns +/- 20.2
  intra_pred_dc_128_w32_8bpc_rvv:      75.2 +/- 10.7           38.4 ns +/- 5.9    ( 5.09x)
  intra_pred_dc_128_w32_16bpc_c:      932.1 +/- 51.2          476.2 ns +/- 38.1
  intra_pred_dc_128_w64_8bpc_c:       814.2 +/- 55.7          416.0 ns +/- 37.5
  intra_pred_dc_128_w64_8bpc_rvv:     191.3 +/- 21.1           97.7 ns +/- 12.3   ( 4.16x)
  intra_pred_dc_128_w64_16bpc_c:     2088.5 +/- 85.6         1067.0 ns +/- 75.8
  intra_pred_dc_left_w4_8bpc_c:       141.6 +/- 17.5           72.3 ns +/- 10.0
  intra_pred_dc_left_w4_8bpc_rvv:      96.7 +/- 13.7           49.4 ns +/- 7.6    ( 1.41x)
  intra_pred_dc_left_w4_16bpc_c:      197.3 +/- 20.7          100.8 ns +/- 12.2
  intra_pred_dc_left_w8_8bpc_c:       194.0 +/- 17.8           99.1 ns +/- 10.8
  intra_pred_dc_left_w8_8bpc_rvv:     110.6 +/- 13.0           56.5 ns +/- 7.5    ( 1.71x)
  intra_pred_dc_left_w8_16bpc_c:      358.6 +/- 27.8          183.2 ns +/- 17.8
  intra_pred_dc_left_w16_8bpc_c:      310.1 +/- 22.4          158.4 ns +/- 14.7
  intra_pred_dc_left_w16_8bpc_rvv:    130.1 +/- 12.8           66.5 ns +/- 7.6    ( 2.34x)
  intra_pred_dc_left_w16_16bpc_c:     614.8 +/- 34.3          314.1 ns +/- 25.4
  intra_pred_dc_left_w32_8bpc_c:      543.6 +/- 36.0          277.7 ns +/- 24.5
  intra_pred_dc_left_w32_8bpc_rvv:    144.6 +/- 15.1           73.9 ns +/- 8.9    ( 3.68x)
  intra_pred_dc_left_w32_16bpc_c:    1101.4 +/- 57.5          562.7 ns +/- 44.0
  intra_pred_dc_left_w64_8bpc_c:      979.7 +/- 54.1          500.5 ns +/- 40.2
  intra_pred_dc_left_w64_8bpc_rvv:    257.9 +/- 24.1          131.8 ns +/- 14.6   ( 3.74x)
  intra_pred_dc_left_w64_16bpc_c:    2288.0 +/- 114.4        1168.9 ns +/- 89.7
  intra_pred_dc_top_w4_8bpc_c:        124.6 +/- 16.3           63.7 ns +/- 9.2
  intra_pred_dc_top_w4_8bpc_rvv:       89.8 +/- 13.3           45.9 ns +/- 7.4    ( 1.33x)
  intra_pred_dc_top_w4_16bpc_c:       180.8 +/- 20.8           92.3 ns +/- 12.0
  intra_pred_dc_top_w8_8bpc_c:        189.2 +/- 17.7           96.7 ns +/- 10.7
  intra_pred_dc_top_w8_8bpc_rvv:      103.3 +/- 12.4           52.8 ns +/- 7.1    ( 1.78x)
  intra_pred_dc_top_w8_16bpc_c:       319.4 +/- 24.6          163.2 ns +/- 15.8
  intra_pred_dc_top_w16_8bpc_c:       326.4 +/- 22.3          166.7 ns +/- 15.0
  intra_pred_dc_top_w16_8bpc_rvv:     122.8 +/- 12.1           62.7 ns +/- 7.2    ( 2.61x)
  intra_pred_dc_top_w16_16bpc_c:      633.4 +/- 34.2          323.6 ns +/- 25.7
  intra_pred_dc_top_w32_8bpc_c:       621.5 +/- 37.2          317.5 ns +/- 26.6
  intra_pred_dc_top_w32_8bpc_rvv:     137.7 +/- 14.8           70.4 ns +/- 8.6    ( 4.41x)
  intra_pred_dc_top_w32_16bpc_c:     1158.1 +/- 52.6          591.7 ns +/- 43.7
  intra_pred_dc_top_w64_8bpc_c:      1157.5 +/- 59.6          591.4 ns +/- 46.0
  intra_pred_dc_top_w64_8bpc_rvv:     250.4 +/- 25.0          128.0 ns +/- 14.9   ( 4.53x)
  intra_pred_dc_top_w64_16bpc_c:     2428.9 +/- 115.8        1240.9 ns +/- 93.3
  intra_pred_dc_w4_8bpc_c:            198.1 +/- 28.6          101.2 ns +/- 15.9
  intra_pred_dc_w4_8bpc_rvv:          143.8 +/- 20.3           73.5 ns +/- 11.3   ( 1.33x)
  intra_pred_dc_w4_16bpc_c:           238.4 +/- 24.1          121.8 ns +/- 14.3
  intra_pred_dc_w8_8bpc_c:            285.3 +/- 28.8          145.7 ns +/- 17.1
  intra_pred_dc_w8_8bpc_rvv:          157.9 +/- 16.2           80.7 ns +/- 9.6    ( 1.77x)
  intra_pred_dc_w8_16bpc_c:           422.4 +/- 29.7          215.8 ns +/- 19.8
  intra_pred_dc_w16_8bpc_c:           450.9 +/- 31.7          230.3 ns +/- 21.1
  intra_pred_dc_w16_8bpc_rvv:         179.0 +/- 15.3           91.5 ns +/- 9.5    ( 2.48x)
  intra_pred_dc_w16_16bpc_c:          747.0 +/- 37.7          381.7 ns +/- 29.4
  intra_pred_dc_w32_8bpc_c:           774.5 +/- 44.7          395.7 ns +/- 32.5
  intra_pred_dc_w32_8bpc_rvv:         192.7 +/- 17.4           98.5 ns +/- 10.6   ( 3.96x)
  intra_pred_dc_w32_16bpc_c:         1309.4 +/- 58.3          669.0 ns +/- 49.0
  intra_pred_dc_w64_8bpc_c:          1385.0 +/- 77.7          707.6 ns +/- 57.3
  intra_pred_dc_w64_8bpc_rvv:         305.8 +/- 26.4          156.3 ns +/- 16.3   ( 4.46x)
  intra_pred_dc_w64_16bpc_c:         2636.9 +/- 105.3        1347.2 ns +/- 94.9
This commit is contained in:
Mikołaj Zalewski
2025-11-22 17:40:26 +00:00
parent e9c5800ace
commit bd95380139
2 changed files with 104 additions and 0 deletions
+96
View File
@@ -27,6 +27,102 @@
#include "src/riscv/asm.S"
// void ipred_dc_128_8bpc_rvv(pixel *dst, const ptrdiff_t stride,
// const pixel *const topleft,
// const int width, const int height, const int a,
// const int max_width, const int max_height)
function ipred_dc_128_8bpc_rvv, export=1, ext="v,zba"
li a5, 128 // a5 - value to fill
j dc_common_rvv
endfunc
// void ipred_dc_8bpc_rvv(pixel *dst, const ptrdiff_t stride,
// const pixel *const topleft,
// const int width, const int height, const int a,
// const int max_width, const int max_height)
function ipred_dc_8bpc_rvv, export=1, ext=v
mv t6, a0 // dst
mv a0, a2 // topleft
mv t4, a1 // stride
mv a1, a3 // width
mv a2, a4 // height
jal t0, dc_gen_8bpc_rvv
mv a5, a0 // fill value
mv a0, t6 // dst
mv a1, t4 // stride
j dc_common_rvv
endfunc
// void ipred_dc_left_8bpc_rvv(pixel *dst, const ptrdiff_t stride,
// const pixel *const topleft,
// const int width, const int height, const int a,
// const int max_width, const int max_height)
function ipred_dc_left_8bpc_rvv, export=1, ext=v
mv t6, a0 // dst
mv a0, a2 // topleft
mv t4, a1 // stride
mv a1, a4 // height
jal t0, dc_gen_left_8bpc_rvv
mv a5, a0 // fill value
mv a0, t6 // dst
mv a1, t4 // stride
j dc_common_rvv
endfunc
// void ipred_dc_top_8bpc_rvv(pixel *dst, const ptrdiff_t stride,
// const pixel *const topleft,
// const int width, const int height, const int a,
// const int max_width, const int max_height)
function ipred_dc_top_8bpc_rvv, export=1, ext=v
mv t6, a0 // dst
mv a0, a2 // topleft
mv t4, a1 // stride
mv a1, a3 // width
jal t0, dc_gen_top_8bpc_rvv
mv a5, a0 // fill value
mv a0, t6 // dst
mv a1, t4 // stride
j dc_common_rvv
endfunc
// void dc_common_rvv(pixel *dst, const ptrdiff_t stride,
// const pixel *const unused,
// const int width, const int height, const int value)
function dc_common_rvv, export=1, ext="v,zba"
sh1add t2, a1, a0 // t2 - pointed to N+2 row
vsetvli t0, a3, e8, m1, ta, ma
add t1, a1, a0 // t1 - pointer to N+1 row
vmv.v.x v0, a5
add t3, a1, t2 // t3 - pointer to N+3 row
beq t0, a3, 1f // Whole row fits in register.
vsetvli t0, a3, e8, m2, ta, ma // Try LMUL=2
beq t0, a3, 2f // Whole row fits in register.
// RVV requires VLEN>=128, so LMUL=4 should work.
vsetvli t0, a3, e8, m4, ta, ma
2:
vmv.v.x v0, a5
1:
vse8.v v0, (a0)
sh2add a0, a1, a0
vse8.v v0, (t1)
sh2add t1, a1, t1
vse8.v v0, (t2)
sh2add t2, a1, t2
vse8.v v0, (t3)
sh2add t3, a1, t3
addi a4, a4, -4
bnez a4, 1b
ret
endfunc
// void ipred_v_8bpc_rvv(pixel *dst, const ptrdiff_t stride,
// const pixel *const topleft,
// const int width, const int height, const int a,
+8
View File
@@ -33,6 +33,10 @@ decl_cfl_pred_fn(BF(dav1d_ipred_cfl_128, rvv));
decl_cfl_pred_fn(BF(dav1d_ipred_cfl_top, rvv));
decl_cfl_pred_fn(BF(dav1d_ipred_cfl_left, rvv));
decl_angular_ipred_fn(BF(dav1d_ipred_dc, rvv));
decl_angular_ipred_fn(BF(dav1d_ipred_dc_128, rvv));
decl_angular_ipred_fn(BF(dav1d_ipred_dc_top, rvv));
decl_angular_ipred_fn(BF(dav1d_ipred_dc_left, rvv));
decl_angular_ipred_fn(BF(dav1d_ipred_h, rvv));
decl_angular_ipred_fn(BF(dav1d_ipred_v, rvv));
decl_angular_ipred_fn(BF(dav1d_ipred_paeth, rvv));
@@ -54,6 +58,10 @@ static ALWAYS_INLINE void intra_pred_dsp_init_riscv(Dav1dIntraPredDSPContext *co
c->cfl_pred[TOP_DC_PRED ] = dav1d_ipred_cfl_top_8bpc_rvv;
c->cfl_pred[LEFT_DC_PRED] = dav1d_ipred_cfl_left_8bpc_rvv;
c->intra_pred[DC_PRED ] = dav1d_ipred_dc_8bpc_rvv;
c->intra_pred[DC_128_PRED ] = dav1d_ipred_dc_128_8bpc_rvv;
c->intra_pred[TOP_DC_PRED ] = dav1d_ipred_dc_top_8bpc_rvv;
c->intra_pred[LEFT_DC_PRED ] = dav1d_ipred_dc_left_8bpc_rvv;
c->intra_pred[HOR_PRED ] = dav1d_ipred_h_8bpc_rvv;
c->intra_pred[VERT_PRED ] = dav1d_ipred_v_8bpc_rvv;
c->intra_pred[PAETH_PRED ] = dav1d_ipred_paeth_8bpc_rvv;