[FFmpeg-devel] [PATCH 3/3] lavc/audiodsp: add RISC-V F float vector clip

Rémi Denis-Courmont remi at remlab.net
Wed Sep 14 20:56:52 EEST 2022


Le keskiviikkona 14. syyskuuta 2022, 20.50.31 EEST remi at remlab.net a écrit :
> From: Rémi Denis-Courmont <remi at remlab.net>
> 
> RV64G supports MIN & MAX instructions natively only on floating point
> registers, not general purpose ones. The later would require the Zbb
> extension. Due to that, it is actually faster to perform the clipping
> "properly" in FPU.
> 
> Benchmarked on SiFive U74-MC:
> 
> audiodsp.vector_clipf_c: 29551.5
> audiodsp.vector_clipf_f: 17871.0
> 
> Also tried unrolling with 2 or 8 elements but it gets worse either way.
> ---
>  libavcodec/audiodsp.c            |  2 ++
>  libavcodec/audiodsp.h            |  1 +
>  libavcodec/riscv/Makefile        |  2 ++
>  libavcodec/riscv/audiodsp_init.c | 31 +++++++++++++++++++++
>  libavcodec/riscv/audiodsp_rvf.S  | 46 ++++++++++++++++++++++++++++++++
>  5 files changed, 82 insertions(+)
>  create mode 100644 libavcodec/riscv/Makefile
>  create mode 100644 libavcodec/riscv/audiodsp_init.c
>  create mode 100644 libavcodec/riscv/audiodsp_rvf.S
> 
> diff --git a/libavcodec/audiodsp.c b/libavcodec/audiodsp.c
> index ff43e87dce..eba6e809fd 100644
> --- a/libavcodec/audiodsp.c
> +++ b/libavcodec/audiodsp.c
> @@ -113,6 +113,8 @@ av_cold void ff_audiodsp_init(AudioDSPContext *c)
>      ff_audiodsp_init_arm(c);
>  #elif ARCH_PPC
>      ff_audiodsp_init_ppc(c);
> +#elif ARCH_RISCV
> +    ff_audiodsp_init_riscv(c);
>  #elif ARCH_X86
>      ff_audiodsp_init_x86(c);
>  #endif
> diff --git a/libavcodec/audiodsp.h b/libavcodec/audiodsp.h
> index aa6fa7898b..485b512839 100644
> --- a/libavcodec/audiodsp.h
> +++ b/libavcodec/audiodsp.h
> @@ -55,6 +55,7 @@ typedef struct AudioDSPContext {
>  void ff_audiodsp_init(AudioDSPContext *c);
>  void ff_audiodsp_init_arm(AudioDSPContext *c);
>  void ff_audiodsp_init_ppc(AudioDSPContext *c);
> +void ff_audiodsp_init_riscv(AudioDSPContext *c);
>  void ff_audiodsp_init_x86(AudioDSPContext *c);
> 
>  #endif /* AVCODEC_AUDIODSP_H */
> diff --git a/libavcodec/riscv/Makefile b/libavcodec/riscv/Makefile
> new file mode 100644
> index 0000000000..a1f67ed55b
> --- /dev/null
> +++ b/libavcodec/riscv/Makefile
> @@ -0,0 +1,2 @@
> +OBJS += riscv/audiodsp_init.o \
> +        riscv/audiodsp_rvf.o
> diff --git a/libavcodec/riscv/audiodsp_init.c
> b/libavcodec/riscv/audiodsp_init.c new file mode 100644
> index 0000000000..7ffd7e8162
> --- /dev/null
> +++ b/libavcodec/riscv/audiodsp_init.c
> @@ -0,0 +1,31 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA + */
> +
> +#include "libavutil/attributes.h"
> +#include "libavutil/cpu.h"
> +#include "libavcodec/audiodsp.h"
> +
> +void ff_vector_clipf_rvf(float *dst, const float *src, int len, float min,
> float max); +
> +av_cold void ff_audiodsp_init_riscv(AudioDSPContext *c)
> +{
> +    int flags = av_get_cpu_flags();
> +
> +    if (flags & AV_CPU_FLAG_F)
> +        c->vector_clipf = ff_vector_clipf_rvf;
> +}
> diff --git a/libavcodec/riscv/audiodsp_rvf.S
> b/libavcodec/riscv/audiodsp_rvf.S new file mode 100644
> index 0000000000..148af96ea2
> --- /dev/null
> +++ b/libavcodec/riscv/audiodsp_rvf.S
> @@ -0,0 +1,46 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA + */
> +
> +#include "libavutil/riscv/asm.S"
> +
> +func ff_vector_clipf_rvf, f
> +NOHWF   fmv.w.x fa0, a3
> +NOHWF   fmv.w.v fa1, a4

This should be fmv.w.x, though I don't know a distro that would use the soft 
float ABI. Need more sleep.

> +1:
> +        flw     ft0,   (a1)
> +        flw     ft1,  4(a1)
> +        fmax.s  ft0, ft0, fa0
> +        flw     ft2,  8(a1)
> +        fmax.s  ft1, ft1, fa0
> +        flw     ft3, 12(a1)
> +        fmax.s  ft2, ft2, fa0
> +        addi    a2, a2, -4
> +        fmax.s  ft3, ft3, fa0
> +        addi    a1, a1, 16
> +        fmin.s  ft0, ft0, fa1
> +        fmin.s  ft1, ft1, fa1
> +        fsw     ft0,   (a0)
> +        fmin.s  ft2, ft2, fa1
> +        fsw     ft1,  4(a0)
> +        fmin.s  ft3, ft3, fa1
> +        fsw     ft2,  8(a0)
> +        fsw     ft3, 12(a0)
> +        addi    a0, a0, 16
> +        bnez    a2, 1b
> +        ret
> +endfunc


-- 
Реми Дёни-Курмон
http://www.remlab.net/





More information about the ffmpeg-devel mailing list