From: Shreesh Adiga <16567adigashreesh@gmail.com>
To: ffmpeg-devel@ffmpeg.org
Subject: Re: [FFmpeg-devel] [PATCH] swscale/x86/rgb2rgb: add AVX512ICL version of uyvytoyuv422
Date: Tue, 18 Feb 2025 20:28:19 +0530
Message-ID: <CA+-x59bp0MR3rZaVduv_WkRABW2f3K9DsEtgL65izFqNd-O57Q@mail.gmail.com> (raw)
In-Reply-To: <20250203163330.533628-1-16567adigashreesh@gmail.com>
On Mon, Feb 3, 2025 at 10:03 PM Shreesh Adiga
<16567adigashreesh@gmail.com> wrote:
>
> The scalar loop is replaced with masked AVX512 instructions.
> For extracting the Y from UYVY, vperm2b is used instead of
> various AND and packuswb.
>
> Instead of loading the vectors with interleaved lanes as done
> in AVX2 version, normal load is used. At the end of packuswb,
> for U and V, an extra permute operation is done to get the
> required layout.
>
> AMD 7950x Zen 4 benchmark data:
> uyvytoyuv422_c: 29105.0 ( 1.00x)
> uyvytoyuv422_sse2: 3888.0 ( 7.49x)
> uyvytoyuv422_avx: 3374.2 ( 8.63x)
> uyvytoyuv422_avx2: 2649.8 (10.98x)
> uyvytoyuv422_avx512icl: 1615.0 (18.02x)
>
> Signed-off-by: Shreesh Adiga <16567adigashreesh@gmail.com>
> ---
> libswscale/x86/rgb2rgb.c | 6 ++
> libswscale/x86/rgb_2_rgb.asm | 105 +++++++++++++++++++++++++++++++++++
> 2 files changed, 111 insertions(+)
>
> diff --git a/libswscale/x86/rgb2rgb.c b/libswscale/x86/rgb2rgb.c
> index 4cbed54b35..6601dad233 100644
> --- a/libswscale/x86/rgb2rgb.c
> +++ b/libswscale/x86/rgb2rgb.c
> @@ -2383,6 +2383,9 @@ void ff_uyvytoyuv422_avx(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
> void ff_uyvytoyuv422_avx2(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
> const uint8_t *src, int width, int height,
> int lumStride, int chromStride, int srcStride);
> +void ff_uyvytoyuv422_avx512icl(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
> + const uint8_t *src, int width, int height,
> + int lumStride, int chromStride, int srcStride);
> #endif
>
> #define DEINTERLEAVE_BYTES(cpuext) \
> @@ -2477,6 +2480,9 @@ av_cold void rgb2rgb_init_x86(void)
> }
> if (EXTERNAL_AVX2_FAST(cpu_flags)) {
> uyvytoyuv422 = ff_uyvytoyuv422_avx2;
> + }
> + if (EXTERNAL_AVX512ICL(cpu_flags)) {
> + uyvytoyuv422 = ff_uyvytoyuv422_avx512icl;
> #endif
> }
> #endif
> diff --git a/libswscale/x86/rgb_2_rgb.asm b/libswscale/x86/rgb_2_rgb.asm
> index ca7a481255..6e4df17298 100644
> --- a/libswscale/x86/rgb_2_rgb.asm
> +++ b/libswscale/x86/rgb_2_rgb.asm
> @@ -35,6 +35,20 @@ pb_shuffle2013: db 2, 0, 1, 3, 6, 4, 5, 7, 10, 8, 9, 11, 14, 12, 13, 15
> pb_shuffle2130: db 2, 1, 3, 0, 6, 5, 7, 4, 10, 9, 11, 8, 14, 13, 15, 12
> pb_shuffle1203: db 1, 2, 0, 3, 5, 6, 4, 7, 9, 10, 8, 11, 13, 14, 12, 15
>
> +%if HAVE_AVX512ICL_EXTERNAL
> +; shuffle vector to rearrange packuswb result to be linear
> +shuf_packus: db 0, 1, 2, 3, 16, 17, 18, 19, 32, 33, 34, 35, 48, 49, 50, 51,\
> + 4, 5, 6, 7, 20, 21, 22, 23, 36, 37, 38, 39, 52, 53, 54, 55,\
> + 8, 9, 10, 11, 24, 25, 26, 27, 40, 41, 42, 43, 56, 57, 58, 59,\
> + 12, 13, 14, 15, 28, 29, 30, 31, 44, 45, 46, 47, 60, 61, 62, 63
> +
> +; shuffle vector to combine odd elements from two vectors to extract Y
> +shuf_perm2b: db 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,\
> + 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63,\
> + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,\
> + 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127
> +%endif
> +
> SECTION .text
>
> %macro RSHIFT_COPY 5
> @@ -156,9 +170,20 @@ SHUFFLE_BYTES 1, 2, 0, 3
> ; int lumStride, int chromStride, int srcStride)
> ;-----------------------------------------------------------------------------------------------
> %macro UYVY_TO_YUV422 0
> +%if mmsize == 64
> +; need two more registers to store shuffle vectors for AVX512ICL
> +cglobal uyvytoyuv422, 9, 14, 10, ydst, udst, vdst, src, w, h, lum_stride, chrom_stride, src_stride, wtwo, whalf, tmp, x, back_w
> +%else
> cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_stride, src_stride, wtwo, whalf, tmp, x, back_w
> +%endif
> pxor m0, m0
> +%if mmsize == 64
> + vpternlogd m1, m1, m1, 0xff ; m1 = _mm512_set1_epi8(0xff)
> + movu m8, [shuf_packus]
> + movu m9, [shuf_perm2b]
> +%else
> pcmpeqw m1, m1
> +%endif
> psrlw m1, 8
>
> movsxdifnidn wq, wd
> @@ -188,6 +213,63 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
> and xq, mmsize * 2 - 1
> je .loop_simd
>
> +%if mmsize == 64
> + shr xq, 1
> + mov tmpq, -1
> + shlx tmpq, tmpq, xq
> + not tmpq
> + kmovq k7, tmpq ; write mask for U/V
> + kmovd k1, tmpd ; write mask for 1st half of Y
> + kmovw k3, tmpd ; read mask for 1st vector
> + shr tmpq, 16
> + kmovw k4, tmpd ; read mask for 2nd vector
> + shr tmpq, 16
> + kmovd k2, tmpd ; write mask for 2nd half of Y
> + kmovw k5, tmpd ; read mask for 3rd vector
> + shr tmpd, 16
> + kmovw k6, tmpd ; read mask for 4th vector
> +
> + vmovdqu32 m2{k3}{z}, [srcq + wtwoq ]
> + vmovdqu32 m3{k4}{z}, [srcq + wtwoq + mmsize ]
> + vmovdqu32 m4{k5}{z}, [srcq + wtwoq + mmsize * 2]
> + vmovdqu32 m5{k6}{z}, [srcq + wtwoq + mmsize * 3]
> +
> + ; extract y part 1
> + mova m6, m9
> + vpermi2b m6, m2, m3 ; UYVY UYVY -> YYYY using permute
> + vmovdqu16 [ydstq + wq]{k1}, m6
> +
> + ; extract y part 2
> + mova m7, m9
> + vpermi2b m7, m4, m5 ; UYVY UYVY -> YYYY using permute
> + vmovdqu16 [ydstq + wq + mmsize]{k2}, m7
> +
> + ; extract uv
> + pand m2, m1 ; UxVx...
> + pand m3, m1 ; UxVx...
> + pand m4, m1 ; UxVx...
> + pand m5, m1 ; UxVx...
> + packuswb m2, m3 ; UVUV...
> + packuswb m4, m5 ; UVUV...
> +
> + ; U
> + pand m6, m2, m1 ; UxUx...
> + pand m7, m4, m1 ; UxUx...
> + packuswb m6, m7 ; UUUU
> + vpermb m6, m8, m6
> + vmovdqu8 [udstq + whalfq]{k7}, m6
> +
> + ; V
> + psrlw m2, 8 ; VxVx...
> + psrlw m4, 8 ; VxVx...
> + packuswb m2, m4 ; VVVV
> + vpermb m2, m8, m2
> + vmovdqu8 [vdstq + whalfq]{k7}, m2
> +
> + lea wq, [ wq + 2 * xq]
> + lea wtwoq, [wtwoq + 4 * xq]
> + add whalfq, xq
> +%else
> .loop_scalar:
> mov tmpb, [srcq + wtwoq + 0]
> mov [udstq + whalfq], tmpb
> @@ -206,6 +288,7 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
> add whalfq, 1
> sub xq, 2
> jg .loop_scalar
> +%endif
>
> ; check if simd loop is need
> cmp wq, 0
> @@ -228,6 +311,17 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
> movu m5, [srcq + wtwoq + mmsize * 3]
> %endif
>
> +%if mmsize == 64
> + ; extract y part 1
> + mova m6, m9
> + vpermi2b m6, m2, m3 ; UYVY UYVY -> YYYY using permute
> + movu [ydstq + wq], m6
> +
> + ; extract y part 2
> + mova m7, m9
> + vpermi2b m7, m4, m5 ; UYVY UYVY -> YYYY using permute
> + movu [ydstq + wq + mmsize], m7
> +%else
> ; extract y part 1
> RSHIFT_COPY m6, m2, m4, 1, 0x20 ; UYVY UYVY -> YVYU YVY...
> pand m6, m1; YxYx YxYx...
> @@ -247,6 +341,7 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
>
> packuswb m6, m7 ; YYYY YYYY...
> movu [ydstq + wq + mmsize], m6
> +%endif
>
> ; extract uv
> pand m2, m1 ; UxVx...
> @@ -262,6 +357,9 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
> pand m7, m4, m1 ; UxUx...
>
> packuswb m6, m7 ; UUUU
> +%if mmsize == 64
> + vpermb m6, m8, m6
> +%endif
> movu [udstq + whalfq], m6
>
>
> @@ -269,6 +367,9 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
> psrlw m2, 8 ; VxVx...
> psrlw m4, 8 ; VxVx...
> packuswb m2, m4 ; VVVV
> +%if mmsize == 64
> + vpermb m2, m8, m2
> +%endif
> movu [vdstq + whalfq], m2
>
> add whalfq, mmsize
> @@ -303,4 +404,8 @@ UYVY_TO_YUV422
> INIT_YMM avx2
> UYVY_TO_YUV422
> %endif
> +%if HAVE_AVX512ICL_EXTERNAL
> +INIT_ZMM avx512icl
> +UYVY_TO_YUV422
> +%endif
> %endif
> --
> 2.45.3
>
Hi maintainers,
Would anyone be willing to review this and provide inputs on getting
this accepted?
As a new contributor interested in contributing ASM, I was hoping to
work on https://trac.ffmpeg.org/wiki/SmallASMTasks mentioned AVX512ICL
work.
Thanks,
Shreesh
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2025-02-18 14:58 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-03 16:33 Shreesh Adiga
2025-02-18 14:58 ` Shreesh Adiga [this message]
2025-02-18 15:44 ` James Almer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CA+-x59bp0MR3rZaVduv_WkRABW2f3K9DsEtgL65izFqNd-O57Q@mail.gmail.com \
--to=16567adigashreesh@gmail.com \
--cc=ffmpeg-devel@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git