[PR] avcodec/x86/lossless_videodsp: Optimize add_gradient_pred (PR #23964)

mkver via ffmpeg-devel <[email protected]> Thu, 30 Jul 2026 16:21:18 -0000
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <178542853089.51.15722820931004972984@29965ddac10e>
PR #23964 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23964
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23964.patch

One could replace the pshufb with pslldq in the add_left_pred and add_left_pred_int16 functions; this would avoids some loads and save a few register (no more nonvolatile regs on win64!) and be certainly faster on the early SSSE3 CPUs where pshufb was slow. Yet uops.info says that pshufb has a latency of 1 on Zen5, but pslldq has a latency of 2.


>From ea6ebf9a3b1f32207f285854f523c764e1e52cf5 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Thu, 30 Jul 2026 15:59:53 +0200
Subject: [PATCH 1/3] avcodec/x86/lossless_videodsp: Optimize add_gradient_pred

Combinations of shift and add like
pslldq  m3, m2, 1
paddb   m2, m3
are linear in the input register m2. This implies
that instead of applying the same sequence of shifts and adds
to two different registers and adding said registers
one can just add the register first and then apply
said sequence of shifts and adds once.

Old benchmarks:
  add_gradient_pred_c:           2296.2
  add_gradient_pred_ssse3:        570.4 ( 3.95x)
  add_gradient_pred_avx2:         308.8 ( 7.29x)

New benchmarks:
  add_gradient_pred_c:           2315.6
  add_gradient_pred_ssse3:        344.0 ( 6.72x)
  add_gradient_pred_avx2:         205.2 (11.28x)

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/lossless_videodsp.asm | 23 +++++------------------
 1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/libavcodec/x86/lossless_videodsp.asm b/libavcodec/x86/lossless_videodsp.asm
index 1761a2f08f..53adc67977 100644
--- a/libavcodec/x86/lossless_videodsp.asm
+++ b/libavcodec/x86/lossless_videodsp.asm
@@ -276,7 +276,7 @@ cglobal add_left_pred_int16_unaligned, 4,4,7, dst, src, mask, w, left
 ; void add_gradient_pred(uint8_t *src, const ptrdiff_t stride, const ptrdiff_t width)
 ;---------------------------------------------------------------------------------------------
 %macro ADD_GRADIENT_PRED 0
-cglobal add_gradient_pred, 3,4,5, src, stride, width, tmp
+cglobal add_gradient_pred, 3,4,4, src, stride, width, tmp
     mova         xm0, [pb_15]
 
 ;load src - 1 in xm1
@@ -294,13 +294,13 @@ cglobal add_gradient_pred, 3,4,5, src, stride, width, tmp
 
 .loop:
     lea    tmpq, [srcq + strideq]
-    mova     m2, [tmpq + widthq] ; A = src[x-stride]
+    mova     m2, [srcq + widthq]     ; current val (src[x])
+    paddb    m2, [tmpq + widthq]     ; add A = src[x-stride]
     movu     m3, [tmpq + widthq - 1] ; B = src[x - (stride + 1)]
-    mova     m4, [srcq + widthq] ; current val (src[x])
 
-    psubb    m2, m3; A - B
+    psubb    m2, m3                  ; cur + A - B
 
-; prefix sum A-B
+; prefix sum
     pslldq   m3, m2, 1
     paddb    m2, m3
     pslldq   m3, m2, 2
@@ -310,19 +310,6 @@ cglobal add_gradient_pred, 3,4,5, src, stride, width, tmp
     pslldq   m3, m2, 8
     paddb    m2, m3
 
-; prefix sum current val
-    pslldq   m3, m4, 1
-    paddb    m4, m3
-    pslldq   m3, m4, 2
-    paddb    m4, m3
-    pslldq   m3, m4, 4
-    paddb    m4, m3
-    pslldq   m3, m4, 8
-    paddb    m4, m3
-
-; last sum
-    paddb                    m2, m4 ; current + (A - B)
-
     paddb                   xm1, xm2 ; += C
     mova        [srcq + widthq], xm1 ; store
 
-- 
2.52.0


>From b064dd6b1ef2bc046270605d88389c99c814f8d0 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Thu, 30 Jul 2026 16:19:56 +0200
Subject: [PATCH 2/3] avcodec/x86/lossless_videodsp: Hoist calculation out of
 loop

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/lossless_videodsp.asm | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/libavcodec/x86/lossless_videodsp.asm b/libavcodec/x86/lossless_videodsp.asm
index 53adc67977..833b581744 100644
--- a/libavcodec/x86/lossless_videodsp.asm
+++ b/libavcodec/x86/lossless_videodsp.asm
@@ -276,7 +276,7 @@ cglobal add_left_pred_int16_unaligned, 4,4,7, dst, src, mask, w, left
 ; void add_gradient_pred(uint8_t *src, const ptrdiff_t stride, const ptrdiff_t width)
 ;---------------------------------------------------------------------------------------------
 %macro ADD_GRADIENT_PRED 0
-cglobal add_gradient_pred, 3,4,4, src, stride, width, tmp
+cglobal add_gradient_pred, 3,3,4, src, stride, width
     mova         xm0, [pb_15]
 
 ;load src - 1 in xm1
@@ -291,12 +291,13 @@ cglobal add_gradient_pred, 3,4,4, src, stride, width, tmp
     add    srcq, widthq
     neg  widthq
     neg strideq
+    add strideq, srcq
+    DEFINE_ARGS src, top, width
 
 .loop:
-    lea    tmpq, [srcq + strideq]
     mova     m2, [srcq + widthq]     ; current val (src[x])
-    paddb    m2, [tmpq + widthq]     ; add A = src[x-stride]
-    movu     m3, [tmpq + widthq - 1] ; B = src[x - (stride + 1)]
+    paddb    m2, [topq + widthq]     ; add A = src[x-stride]
+    movu     m3, [topq + widthq - 1] ; B = src[x - (stride + 1)]
 
     psubb    m2, m3                  ; cur + A - B
 
-- 
2.52.0


>From 6e999b2e1fe1326806ccdd363ee00f3bce43f1bb Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Thu, 30 Jul 2026 16:21:12 +0200
Subject: [PATCH 3/3] avcodec/x86/lossless_videodsp: Use memory operand where
 possible

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/x86/lossless_videodsp.asm | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/x86/lossless_videodsp.asm b/libavcodec/x86/lossless_videodsp.asm
index 833b581744..5815c8e5ae 100644
--- a/libavcodec/x86/lossless_videodsp.asm
+++ b/libavcodec/x86/lossless_videodsp.asm
@@ -280,10 +280,10 @@ cglobal add_gradient_pred, 3,3,4, src, stride, width
     mova         xm0, [pb_15]
 
 ;load src - 1 in xm1
-    movd         xm1, [srcq-1]
 %if cpuflag(avx2)
-    vpbroadcastb xm1, xm1
+    vpbroadcastb xm1, [srcq-1]
 %else
+    movd         xm1, [srcq-1]
     pxor         xm2, xm2
     pshufb       xm1, xm2
 %endif
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]