[x265] [PATCH 1 of 2] asm_arm: rewrite NEON version of count_nonzero*

Min Chen chenm003 at 163.com
Thu Jun 9 20:35:08 CEST 2016


# HG changeset patch
# User Min Chen <min.chen at multicorewareinc.com>
# Date 1465497292 18000
# Node ID 7dce8656504fdf8d25f67c7a97b781a031bbdf8a
# Parent  0af296185f7ae3e05493ecf164046ddfec085bb3
asm_arm: rewrite NEON version of count_nonzero*
Origin:
count_nonzero[4x4]      1.09x    20.88           22.69
count_nonzero[8x8]      1.25x    22.65           28.23
count_nonzero[16x16]    1.74x    30.91           53.67
count_nonzero[32x32]    2.31x    64.70           149.60

New:
count_nonzero[4x4]      1.13x    20.04           22.71
count_nonzero[8x8]      1.33x    21.02           27.95
count_nonzero[16x16]    2.02x    26.72           53.95
count_nonzero[32x32]    2.95x    50.76           149.61
---
 source/common/arm/blockcopy8.S |  230 +++++++++++++++++++++++++++-------------
 1 files changed, 158 insertions(+), 72 deletions(-)

diff -r 0af296185f7a -r 7dce8656504f source/common/arm/blockcopy8.S
--- a/source/common/arm/blockcopy8.S	Tue Jun 07 09:20:11 2016 +0530
+++ b/source/common/arm/blockcopy8.S	Thu Jun 09 13:34:52 2016 -0500
@@ -664,89 +664,175 @@
 
 // int  count_nonzero_c(const int16_t* quantCoeff)
 function x265_count_nonzero_4_neon
-    veor            d4, d4
-.rept 2
-    vld1.s16        {d0}, [r0]!
-    vld1.s16        {d1}, [r0]!
-    vclz.i16        d2, d0
-    vclz.i16        d3, d1
-    vshr.u16        q1, #4
-    vadd.u16        d2, d3
-    vadd.u16        d4, d2
-.endr
-    vpadd.u16       d4, d4
-    vpadd.u16       d4, d4
-    vmov.u16        r12, d4[0]
-    rsb             r0, r12, #16
+    vld1.s16        {d0-d3}, [r0]
+    vceq.u16        q0, #0
+    vceq.u16        q1, #0
+    eor             r1, r1
+    vtrn.8          q0, q1
+
+    vshr.u8         q0, #7
+
+    vadd.u8         d0, d1
+    vshr.u64        d1, d0, #32
+    vadd.u8         d0, d1
+    vmov.u32        r0, d0[0]
+    usad8           r0, r0, r1
+    rsb             r0, #16
     bx              lr
 endfunc
 
 function x265_count_nonzero_8_neon
-    veor            q8, q8
-.rept 4
-    vld1.s16        {q0}, [r0]!
-    vld1.s16        {q1}, [r0]!
-    vclz.i16        q2, q0
-    vclz.i16        q3, q1
-    vshr.u16        q2, #4
-    vshr.u16        q3, #4
-    vadd.u16        q2, q3
-    vadd.u16        q8, q2
-.endr
-    vadd.u16        d16, d17
-    vpadd.u16       d16, d16
-    vpadd.u16       d16, d16
-    vmov.u16        r12, d16[0]
-    rsb             r0, r12, #64
+    vldm            r0, {q8-q15}
+    eor             r1, r1
+    vceq.u16        q8, #0
+    vceq.u16        q9, #0
+    vceq.u16        q10, #0
+    vceq.u16        q11, #0
+    vceq.u16        q12, #0
+    vceq.u16        q13, #0
+    vceq.u16        q14, #0
+    vceq.u16        q15, #0
+
+    vtrn.8          q8, q9
+    vtrn.8          q10, q11
+    vtrn.8          q12, q13
+    vtrn.8          q14, q15
+
+    vadd.s8         q8, q10
+    vadd.s8         q12, q14
+    vadd.s8         q8, q12
+
+    vadd.s8         d16, d17
+    vshr.u64        d17, d16, #32
+    vadd.s8         d16, d17
+    vabs.s8         d16, d16
+
+    vmov.u32        r0, d16[0]
+    usad8           r0, r0, r1
+    rsb             r0, #64
     bx              lr
 endfunc
 
 function x265_count_nonzero_16_neon
-    veor            q2, q2
-.rept 16
-    vld1.s16        {q0, q1}, [r0]!
-    vclz.i16        q8, q0
-    vclz.i16        q9, q1
-    vshr.u16        q8, #4
-    vshr.u16        q9, #4
-    vadd.u16        q8, q9
-    vadd.u16        q2, q8
+    vldm            r0!, {q8-q15}
+    eor             r1, r1
+    vceq.u16        q8, #0
+    vceq.u16        q9, #0
+    vceq.u16        q10, #0
+    vceq.u16        q11, #0
+    vceq.u16        q12, #0
+    vceq.u16        q13, #0
+    vceq.u16        q14, #0
+    vceq.u16        q15, #0
+
+    vtrn.8          q8, q9
+    vtrn.8          q10, q11
+    vtrn.8          q12, q13
+    vtrn.8          q14, q15
+
+    vmov            q0, q8
+    vmov            q1, q10
+    vmov            q2, q12
+    vmov            q3, q14
+
+.rept 3
+    vldm            r0!, {q8-q15}
+    vceq.u16        q8, #0
+    vceq.u16        q9, #0
+    vceq.u16        q10, #0
+    vceq.u16        q11, #0
+    vceq.u16        q12, #0
+    vceq.u16        q13, #0
+    vceq.u16        q14, #0
+    vceq.u16        q15, #0
+
+    vtrn.8          q8, q9
+    vtrn.8          q10, q11
+    vtrn.8          q12, q13
+    vtrn.8          q14, q15
+
+    vadd.s8         q0, q8
+    vadd.s8         q1, q10
+    vadd.s8         q2, q12
+    vadd.s8         q3, q14
 .endr
-    vadd.u16        d4, d5
-    vpadd.u16       d4, d4
-    vpadd.u16       d4, d4
 
-    vmov.u16        r12, d4[0]
-    rsb             r0, r12, #256
+    vadd.s8         q0, q1
+    vadd.s8         q2, q3
+    vadd.s8         q0, q2                      // dynamic range is 4+1 bits
+
+    vadd.s8         d0, d1
+    vshr.u64        d1, d0, #32
+    vadd.s8         d0, d1
+    vabs.s8         d0, d0                      // maximum value of each element are 64
+
+    vmov.u32        r0, d0[0]
+    usad8           r0, r0, r1
+    rsb             r0, #256
     bx              lr
 endfunc
 
 function x265_count_nonzero_32_neon
-    veor            q12, q12
-.rept 32
-    vld1.s16        {q0, q1}, [r0]!
-    vld1.s16        {q2, q3}, [r0]!
+    vldm            r0!, {q8-q15}
+    vceq.u16        q8, #0
+    vceq.u16        q9, #0
+    vceq.u16        q10, #0
+    vceq.u16        q11, #0
+    vceq.u16        q12, #0
+    vceq.u16        q13, #0
+    vceq.u16        q14, #0
+    vceq.u16        q15, #0
 
-    vclz.i16        q8, q0
-    vclz.i16        q9, q1
-    vclz.i16        q10, q2
-    vclz.i16        q11, q3
+    vtrn.8          q8, q9
+    vtrn.8          q10, q11
+    vtrn.8          q12, q13
+    vtrn.8          q14, q15
 
-    vshr.u16        q8, #4
-    vshr.u16        q9, #4
-    vshr.u16        q10, #4
-    vshr.u16        q11, #4
+    mov             r1, #15
 
-    vadd.u16        q8, q9
-    vadd.u16        q10, q11
-    vadd.u16        q8, q10
-    vadd.u16        q12, q8
-.endr
-    vadd.u16        d24, d25
-    vpadd.u16       d24, d24
-    vpadd.u16       d24, d24
+    vmov            q0, q8
+    vmov            q1, q10
+    vmov            q2, q12
+    vmov            q3, q14
 
-    vmov.u16        r12, d24[0]
-    rsb             r0, r12, #1024
+.loop:    
+    vldm            r0!, {q8-q15}
+    subs            r1, #1
+
+    vceq.u16        q8, #0
+    vceq.u16        q9, #0
+    vceq.u16        q10, #0
+    vceq.u16        q11, #0
+    vceq.u16        q12, #0
+    vceq.u16        q13, #0
+    vceq.u16        q14, #0
+    vceq.u16        q15, #0
+
+    vtrn.8          q8, q9
+    vtrn.8          q10, q11
+    vtrn.8          q12, q13
+    vtrn.8          q14, q15
+
+    vadd.s8         q0, q8
+    vadd.s8         q1, q10
+    vadd.s8         q2, q12
+    vadd.s8         q3, q14
+    bgt            .loop
+
+    // sum
+    vadd.s8         q0, q1
+    vadd.s8         q2, q3
+    vadd.s8         q0, q2                      // dynamic range is 6+1 bits
+
+    vaddl.s8        q0, d0, d1
+    vadd.s16        d0, d1
+    vshr.u64        d1, d0, #32
+    vadd.s16        d0, d1
+    vabs.s16        d0, d0                      //  maximum value of each element are 512
+
+    vmov.u32        r0, d0[0]
+    uasx            r0, r0, r0
+    mov             r0, r0, lsr 16
+    rsb             r0, #1024
     bx              lr
 endfunc



More information about the x265-devel mailing list