diff mbox

[FFmpeg-devel,3/3] avcodec/h264: sse2 and avx 4:2:2 idct add8 10-bit functions

Message ID 20161129115235.8937-4-jdarnley@obe.tv
State Accepted
Commit 13d71c28cc44dd049d27a0a2e909add46ed1d5d0
Headers show

Commit Message

James Darnley Nov. 29, 2016, 11:52 a.m. UTC
sse2:
complex: 4.13x faster (1514 vs. 367 cycles)
simple:  4.38x faster (1836 vs. 419 cycles)

avx:
complex: 1.07x faster (260 vs. 244 cycles)
simple:  1.03x faster (284 vs. 274 cycles)
---
 libavcodec/x86/h264_idct_10bit.asm | 53 ++++++++++++++++++++++++++++++++++++++
 libavcodec/x86/h264dsp_init.c      | 13 ++++++++--
 2 files changed, 64 insertions(+), 2 deletions(-)

Comments

Carl Eugen Hoyos Nov. 29, 2016, 2:30 p.m. UTC | #1
2016-11-29 12:52 GMT+01:00 James Darnley <jdarnley@obe.tv>:
> sse2:
> complex: 4.13x faster (1514 vs. 367 cycles)
> simple:  4.38x faster (1836 vs. 419 cycles)
>
> avx:
> complex: 1.07x faster (260 vs. 244 cycles)
> simple:  1.03x faster (284 vs. 274 cycles)

What are you comparing?

Carl Eugen
James Darnley Nov. 29, 2016, 4:14 p.m. UTC | #2
On 2016-11-29 15:30, Carl Eugen Hoyos wrote:
> 2016-11-29 12:52 GMT+01:00 James Darnley <jdarnley@obe.tv>:
>> sse2:
>> complex: 4.13x faster (1514 vs. 367 cycles)
>> simple:  4.38x faster (1836 vs. 419 cycles)
>>
>> avx:
>> complex: 1.07x faster (260 vs. 244 cycles)
>> simple:  1.03x faster (284 vs. 274 cycles)
> 
> What are you comparing?

I stuck a timer around the call to the h264dsp function in
libavcodec/h264_mb_template.c.  Using STOP_TIMER(__func__) let me get a
different message for each function created.  The two functions my code
was called from were hl_decode_mb_simple_16 and hl_decode_mb_complex.

The video being decoded was one from fate concatenated together several
times.

The AVX comparison is it versus SSE2.
Carl Eugen Hoyos Nov. 29, 2016, 8:09 p.m. UTC | #3
2016-11-29 17:14 GMT+01:00 James Darnley <jdarnley@obe.tv>:
> On 2016-11-29 15:30, Carl Eugen Hoyos wrote:
>> 2016-11-29 12:52 GMT+01:00 James Darnley <jdarnley@obe.tv>:
>>> sse2:
>>> complex: 4.13x faster (1514 vs. 367 cycles)
>>> simple:  4.38x faster (1836 vs. 419 cycles)
>>>
>>> avx:
>>> complex: 1.07x faster (260 vs. 244 cycles)
>>> simple:  1.03x faster (284 vs. 274 cycles)
>>
>> What are you comparing?

> The AVX comparison is it versus SSE2.

This wasn't obvious to me.

Thank you, Carl Eugen
James Darnley Nov. 29, 2016, 9:31 p.m. UTC | #4
On 2016-11-29 21:09, Carl Eugen Hoyos wrote:
> 2016-11-29 17:14 GMT+01:00 James Darnley <jdarnley@obe.tv>:
>> On 2016-11-29 15:30, Carl Eugen Hoyos wrote:
>>> 2016-11-29 12:52 GMT+01:00 James Darnley <jdarnley@obe.tv>:
>>>> sse2:
>>>> complex: 4.13x faster (1514 vs. 367 cycles)
>>>> simple:  4.38x faster (1836 vs. 419 cycles)
>>>>
>>>> avx:
>>>> complex: 1.07x faster (260 vs. 244 cycles)
>>>> simple:  1.03x faster (284 vs. 274 cycles)
>>>
>>> What are you comparing?
> 
>> The AVX comparison is it versus SSE2.
> 
> This wasn't obvious to me.

Ah.  I will try to clarify the message.
James Darnley Nov. 30, 2016, 12:10 p.m. UTC | #5
On 2016-11-29 21:09, Carl Eugen Hoyos wrote:
> 2016-11-29 17:14 GMT+01:00 James Darnley <jdarnley@obe.tv>:
>> On 2016-11-29 15:30, Carl Eugen Hoyos wrote:
>>> 2016-11-29 12:52 GMT+01:00 James Darnley <jdarnley@obe.tv>:
>>>> sse2:
>>>> complex: 4.13x faster (1514 vs. 367 cycles)
>>>> simple:  4.38x faster (1836 vs. 419 cycles)
>>>>
>>>> avx:
>>>> complex: 1.07x faster (260 vs. 244 cycles)
>>>> simple:  1.03x faster (284 vs. 274 cycles)
>>>
>>> What are you comparing?
> 
>> The AVX comparison is it versus SSE2.
> 
> This wasn't obvious to me.

I've made it more verbose but I'm not sure whether it is any better.
Care to give your opinion Carl?

>     Nehalem:
>      - sse2:
>        - complex: 4.13x faster (1514 vs. 367 cycles)
>        - simple:  4.38x faster (1836 vs. 419 cycles)
> 
>     Haswell:
>      - sse2:
>        - complex: 3.61x faster ( 936 vs. 260 cycles)
>        - simple:  3.97x faster (1126 vs. 284 cycles)
>      - avx (versus sse2):
>        - complex: 1.07x faster (260 vs. 244 cycles)
>        - simple:  1.03x faster (284 vs. 274 cycles)

I included the sse2 results for the Haswell to show that the avx is
(slightly) better.
Ronald S. Bultje Nov. 30, 2016, 12:57 p.m. UTC | #6
Hi,

On Wed, Nov 30, 2016 at 7:10 AM, James Darnley <jdarnley@obe.tv> wrote:

> On 2016-11-29 21:09, Carl Eugen Hoyos wrote:
> > 2016-11-29 17:14 GMT+01:00 James Darnley <jdarnley@obe.tv>:
> >> On 2016-11-29 15:30, Carl Eugen Hoyos wrote:
> >>> 2016-11-29 12:52 GMT+01:00 James Darnley <jdarnley@obe.tv>:
> >>>> sse2:
> >>>> complex: 4.13x faster (1514 vs. 367 cycles)
> >>>> simple:  4.38x faster (1836 vs. 419 cycles)
> >>>>
> >>>> avx:
> >>>> complex: 1.07x faster (260 vs. 244 cycles)
> >>>> simple:  1.03x faster (284 vs. 274 cycles)
> >>>
> >>> What are you comparing?
> >
> >> The AVX comparison is it versus SSE2.
> >
> > This wasn't obvious to me.
>
> I've made it more verbose but I'm not sure whether it is any better.
> Care to give your opinion Carl?
>
> >     Nehalem:
> >      - sse2:
> >        - complex: 4.13x faster (1514 vs. 367 cycles)
> >        - simple:  4.38x faster (1836 vs. 419 cycles)
> >
> >     Haswell:
> >      - sse2:
> >        - complex: 3.61x faster ( 936 vs. 260 cycles)
> >        - simple:  3.97x faster (1126 vs. 284 cycles)
> >      - avx (versus sse2):
> >        - complex: 1.07x faster (260 vs. 244 cycles)
> >        - simple:  1.03x faster (284 vs. 274 cycles)
>
> I included the sse2 results for the Haswell to show that the avx is
> (slightly) better.


Ah! Now it makes sense. I had no idea why your SSE2 results changed from
367 (SSE2 vs. C) to 260 cycles (AVX vs. SSE2).

Ronald
James Darnley Nov. 30, 2016, 8:40 p.m. UTC | #7
On 2016-11-30 13:57, Ronald S. Bultje wrote:
> On Wed, Nov 30, 2016 at 7:10 AM, James Darnley <jdarnley@obe.tv> wrote:
>>>     Nehalem:
>>>      - sse2:
>>>        - complex: 4.13x faster (1514 vs. 367 cycles)
>>>        - simple:  4.38x faster (1836 vs. 419 cycles)
>>>
>>>     Haswell:
>>>      - sse2:
>>>        - complex: 3.61x faster ( 936 vs. 260 cycles)
>>>        - simple:  3.97x faster (1126 vs. 284 cycles)
>>>      - avx (versus sse2):
>>>        - complex: 1.07x faster (260 vs. 244 cycles)
>>>        - simple:  1.03x faster (284 vs. 274 cycles)
>>
>> I included the sse2 results for the Haswell to show that the avx is
>> (slightly) better.
> 
> 
> Ah! Now it makes sense. I had no idea why your SSE2 results changed from
> 367 (SSE2 vs. C) to 260 cycles (AVX vs. SSE2).

Great.  If there are no further comments I will push later tonight.

First I need to correct the micro-architecture names.  Then I will
rebase onto the latest master and push.
diff mbox

Patch

diff --git a/libavcodec/x86/h264_idct_10bit.asm b/libavcodec/x86/h264_idct_10bit.asm
index 4f7491d..9fd05ab 100644
--- a/libavcodec/x86/h264_idct_10bit.asm
+++ b/libavcodec/x86/h264_idct_10bit.asm
@@ -351,6 +351,59 @@  IDCT_ADD8
 %endif
 
 ;-----------------------------------------------------------------------------
+; void ff_h264_idct_add8_422_10(pixel **dst, const int *block_offset,
+;                               int16_t *block, int stride,
+;                               const uint8_t nnzc[6*8])
+;-----------------------------------------------------------------------------
+%assign last_block 44
+
+%macro IDCT_ADD8_422 0
+
+cglobal h264_idct_add8_422_10, 5, 8, 7
+    movsxdifnidn r3, r3d
+%if ARCH_X86_64
+    mov      r7, r0
+%endif
+
+    add      r2, 1024
+    mov      r0, [r0]
+    ADD16_OP_INTRA 16, 4+ 6*8
+    ADD16_OP_INTRA 18, 4+ 7*8
+    ADD16_OP_INTRA 24, 4+ 8*8 ; i+4
+    ADD16_OP_INTRA 26, 4+ 9*8 ; i+4
+    add      r2, 1024-128*4
+
+%if ARCH_X86_64
+    mov      r0, [r7+gprsize]
+%else
+    mov      r0, r0m
+    mov      r0, [r0+gprsize]
+%endif
+
+    ADD16_OP_INTRA 32, 4+11*8
+    ADD16_OP_INTRA 34, 4+12*8
+    ADD16_OP_INTRA 40, 4+13*8 ; i+4
+    ADD16_OP_INTRA 42, 4+14*8 ; i+4
+REP_RET
+    AC 16
+    AC 18
+    AC 24 ; i+4
+    AC 26 ; i+4
+    AC 32
+    AC 34
+    AC 40 ; i+4
+    AC 42 ; i+4
+
+%endmacro
+
+INIT_XMM sse2
+IDCT_ADD8_422
+%if HAVE_AVX_EXTERNAL
+INIT_XMM avx
+IDCT_ADD8_422
+%endif
+
+;-----------------------------------------------------------------------------
 ; void ff_h264_idct8_add_10(pixel *dst, int16_t *block, int stride)
 ;-----------------------------------------------------------------------------
 %macro IDCT8_1D 2
diff --git a/libavcodec/x86/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c
index ed52c4d..c6c643a 100644
--- a/libavcodec/x86/h264dsp_init.c
+++ b/libavcodec/x86/h264dsp_init.c
@@ -80,6 +80,9 @@  IDCT_ADD_REP_FUNC2(, 8, 10, avx)
 
 IDCT_ADD_REP_FUNC2(, 8_422, 8, mmx)
 
+IDCT_ADD_REP_FUNC2(, 8_422, 10, sse2)
+IDCT_ADD_REP_FUNC2(, 8_422, 10, avx)
+
 void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul);
 void ff_h264_luma_dc_dequant_idct_sse2(int16_t *output, int16_t *input, int qmul);
 
@@ -319,8 +322,11 @@  av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth,
             c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_sse2;
 
             c->h264_idct_add16 = ff_h264_idct_add16_10_sse2;
-            if (chroma_format_idc <= 1)
+            if (chroma_format_idc <= 1) {
                 c->h264_idct_add8 = ff_h264_idct_add8_10_sse2;
+            } else {
+                c->h264_idct_add8 = ff_h264_idct_add8_422_10_sse2;
+            }
             c->h264_idct_add16intra = ff_h264_idct_add16intra_10_sse2;
 #if HAVE_ALIGNED_STACK
             c->h264_idct8_add  = ff_h264_idct8_add_10_sse2;
@@ -359,8 +365,11 @@  av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth,
             c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_avx;
 
             c->h264_idct_add16 = ff_h264_idct_add16_10_avx;
-            if (chroma_format_idc <= 1)
+            if (chroma_format_idc <= 1) {
                 c->h264_idct_add8 = ff_h264_idct_add8_10_avx;
+            } else {
+                c->h264_idct_add8 = ff_h264_idct_add8_422_10_avx;
+            }
             c->h264_idct_add16intra = ff_h264_idct_add16intra_10_avx;
 #if HAVE_ALIGNED_STACK
             c->h264_idct8_add  = ff_h264_idct8_add_10_avx;