From 32cd5f2a5c50e55a9ef1709b0d527a202fac64b2 Mon Sep 17 00:00:00 2001 From: nihui Date: Thu, 23 Nov 2017 21:52:57 +0800 Subject: [PATCH] use mul for the first multiply, drop accumulator clear instructions, about 5% speed performance gains --- src/layer/arm/convolution_3x3.h | 45 ++++++++------------------------- src/layer/arm/convolution_5x5.h | 31 +++++++++++------------ src/layer/arm/convolution_7x7.h | 20 +++++++-------- 3 files changed, 36 insertions(+), 60 deletions(-) diff --git a/src/layer/arm/convolution_3x3.h b/src/layer/arm/convolution_3x3.h index 8bfaddda1..a2df27c7c 100644 --- a/src/layer/arm/convolution_3x3.h +++ b/src/layer/arm/convolution_3x3.h @@ -79,9 +79,7 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke for (; nn>0; nn--) { float32x4_t _sum1 = vld1q_f32(outptr); - float32x4_t _sum2 = vdupq_n_f32(0.f); float32x4_t _sum3 = vld1q_f32(outptr2); - float32x4_t _sum4 = vdupq_n_f32(0.f); float32x4_t _r00 = vld1q_f32(r0); float32x4_t _r00n = vld1q_f32(r0 + 4); @@ -104,7 +102,7 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke float32x4_t _r32 = vextq_f32(_r30, _r30n, 2); _sum1 = vfmaq_laneq_f32(_sum1, _r00, _k0123, 0); - _sum2 = vfmaq_laneq_f32(_sum2, _r01, _k0123, 1); + float32x4_t _sum2 = vmulq_laneq_f32(_r01, _k0123, 1); _sum1 = vfmaq_laneq_f32(_sum1, _r02, _k0123, 2); _sum2 = vfmaq_laneq_f32(_sum2, _r10, _k3456, 0); _sum1 = vfmaq_laneq_f32(_sum1, _r11, _k3456, 1); @@ -114,7 +112,7 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke _sum1 = vfmaq_laneq_f32(_sum1, _r22, _k6789, 2); _sum3 = vfmaq_laneq_f32(_sum3, _r10, _k0123, 0); - _sum4 = vfmaq_laneq_f32(_sum4, _r11, _k0123, 1); + float32x4_t _sum4 = vmulq_laneq_f32(_r11, _k0123, 1); _sum3 = vfmaq_laneq_f32(_sum3, _r12, _k0123, 2); _sum4 = vfmaq_laneq_f32(_sum4, _r20, _k3456, 0); _sum3 = vfmaq_laneq_f32(_sum3, _r21, _k3456, 1); @@ -140,16 +138,10 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke if (nn > 0) { asm volatile( - "veor q6, q6 \n" - "veor q15, q15 \n" - "pld [%3, #192] \n" "vld1.f32 {d18-d20}, [%3 :64] \n"// r0 "add %3, #16 \n" - "veor q13, q13 \n" - "veor q14, q14 \n" - "vext.32 q11, q9, q10, #1 \n" "vext.32 q12, q9, q10, #2 \n" @@ -159,8 +151,8 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "vld1.f32 {d14-d15}, [%1 :64] \n"// _sum "vmla.f32 q7, q9, %e14[0] \n" - "vmla.f32 q6, q11, %e14[1] \n" - "vmla.f32 q13, q12, %f14[0] \n" + "vmul.f32 q6, q11, %e14[1] \n" + "vmul.f32 q13, q12, %f14[0] \n" "pld [%4, #192] \n" "vld1.f32 {d18-d20}, [%4] \n"// r1 @@ -178,8 +170,8 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "vld1.f32 {d16-d17}, [%2] \n"// _sum2 "vmla.f32 q8, q9, %e14[0] \n" - "vmla.f32 q14, q11, %e14[1] \n" - "vmla.f32 q15, q12, %f14[0] \n" + "vmul.f32 q14, q11, %e14[1] \n" + "vmul.f32 q15, q12, %f14[0] \n" "pld [%5, #192] \n" "vld1.f32 {d18-d20}, [%5 :64] \n"// r2 @@ -210,17 +202,13 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "vmla.f32 q15, q12, %f16[0] \n" "vadd.f32 q7, q7, q6 \n" - "veor q6, q6 \n" "pld [%3, #192] \n" "vld1.f32 {d18-d20}, [%3 :64] \n"// r0 "vadd.f32 q8, q8, q14 \n" - "veor q14, q14 \n" "vadd.f32 q7, q7, q13 \n" - "veor q13, q13 \n" "vadd.f32 q8, q8, q15 \n" - "veor q15, q15 \n" "vext.32 q11, q9, q10, #1 \n" "vext.32 q12, q9, q10, #2 \n" @@ -346,7 +334,6 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke for (; nn>0; nn--) { float32x4_t _sum1 = vld1q_f32(outptr); - float32x4_t _sum2 = vdupq_n_f32(0.f); float32x4_t _r00 = vld1q_f32(r0); float32x4_t _r00n = vld1q_f32(r0 + 4); @@ -364,7 +351,7 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke float32x4_t _r22 = vextq_f32(_r20, _r20n, 2); _sum1 = vfmaq_laneq_f32(_sum1, _r00, _k0123, 0); - _sum2 = vfmaq_laneq_f32(_sum2, _r01, _k0123, 1); + float32x4_t _sum2 = vmulq_laneq_f32(_r01, _k0123, 1); _sum1 = vfmaq_laneq_f32(_sum1, _r02, _k0123, 2); _sum2 = vfmaq_laneq_f32(_sum2, _r10, _k3456, 0); _sum1 = vfmaq_laneq_f32(_sum1, _r11, _k3456, 1); @@ -390,9 +377,6 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "vld1.f32 {d16-d18}, [%2] \n"// r0 "add %2, #16 \n" - "veor q13, q13 \n" - "veor q14, q14 \n" - "vext.32 q10, q8, q9, #1 \n" "vext.32 q11, q8, q9, #2 \n" @@ -402,8 +386,8 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "vld1.f32 {d14-d15}, [%1] \n"// _sum "vmla.f32 q7, q8, %e10[0] \n" - "vmla.f32 q13, q10, %e10[1] \n" - "vmla.f32 q14, q11, %f10[0] \n" + "vmul.f32 q13, q10, %e10[1] \n" + "vmul.f32 q14, q11, %f10[0] \n" "pld [%3, #192] \n" "vld1.f32 {d16-d18}, [%3] \n"// r1 @@ -434,9 +418,7 @@ static void conv3x3s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "add %2, #16 \n" "vadd.f32 q7, q7, q13 \n" - "veor q13, q13 \n" "vadd.f32 q7, q7, q14 \n" - "veor q14, q14 \n" "vext.32 q10, q8, q9, #1 \n" "vext.32 q11, q8, q9, #2 \n" @@ -2364,21 +2346,18 @@ static void conv3x3s2_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "pld [%2, #256] \n" "vld2.f32 {d4-d7}, [%2]! \n" - "veor q10, q10 \n" - "veor q11, q11 \n" - "0: \n" "pld [%1, #128] \n" "vld1.f32 {d0-d1}, [%1] \n" "vmla.f32 q0, q2, %e10[0] \n" - "vmla.f32 q10, q3, %e10[1] \n" + "vmul.f32 q10, q3, %e10[1] \n" "pld [%2, #128] \n" "vld2.f32 {d16-d17}, [%2] \n" "vext.32 q1, q2, q8, #1 \n" - "vmla.f32 q11, q1, %f10[0] \n" + "vmul.f32 q11, q1, %f10[0] \n" "pld [%3, #256] \n" "vld2.f32 {d4-d7}, [%3]! \n" @@ -2408,9 +2387,7 @@ static void conv3x3s2_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "vld2.f32 {d4-d7}, [%2]! \n" "vadd.f32 q0, q0, q10 \n" - "veor q10, q10 \n" "vadd.f32 q0, q0, q11 \n" - "veor q11, q11 \n" "subs %0, #1 \n" "vst1.f32 {d0-d1}, [%1]! \n" diff --git a/src/layer/arm/convolution_5x5.h b/src/layer/arm/convolution_5x5.h index 0547a0683..05c708b3b 100644 --- a/src/layer/arm/convolution_5x5.h +++ b/src/layer/arm/convolution_5x5.h @@ -645,19 +645,19 @@ static void conv5x5s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "0: \n" "vld1.f32 {d14-d15}, [%1] \n"// _sum = vld1q_f32(outptr+j); - "veor q13, q13 \n"// _sum2 = 0; - "veor q14, q14 \n"// _sum3 = 0; +// "veor q13, q13 \n"// _sum2 = 0; +// "veor q14, q14 \n"// _sum3 = 0; "vext.32 q10, q8, q9, #1 \n"// _r01 "vext.32 q11, q8, q9, #2 \n"// _r02 "vext.32 q12, q8, q9, #3 \n"// _r03 "vmla.f32 q7, q8, %e14[0] \n" - "vmla.f32 q13, q10, %e14[1] \n" + "vmul.f32 q13, q10, %e14[1] \n" "pld [%3, #256] \n" - "vmla.f32 q14, q11, %f14[0] \n" + "vmul.f32 q14, q11, %f14[0] \n" "vmul.f32 q15, q12, %f14[1] \n" "vmla.f32 q7, q9, %e15[0] \n" @@ -1019,18 +1019,17 @@ static void conv5x5s2_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke if (nn > 0) { asm volatile( - "veor q15, q15 \n"// _sump3 = 0; - "pld [%1, #128] \n" - "veor q13, q13 \n"// _sump2 = 0; - "pld [%2, #256] \n" - "veor q14, q14 \n"// _sump3 = 0; +// "veor q15, q15 \n"// _sump3 = 0; +// "veor q13, q13 \n"// _sump2 = 0; +// "veor q14, q14 \n"// _sump3 = 0; + "pld [%2, #256] \n" "vld2.f32 {d16-d19}, [%2]! \n"// q8 = 0 2 4 6 q9 = 1 3 5 7 "pld [%2, #256] \n" - "vld2.f32 {d20-d23}, [%2] \n"// q10 = 8 10 12 14 q11 = 9 11 13 15 + "pld [%1, #128] \n" "0: \n" "vld1.f32 {d14-d15}, [%1] \n"// q7 = outptr @@ -1040,12 +1039,12 @@ static void conv5x5s2_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "vext.32 q10, q8, q10, #2 \n"// q10 = 4 6 8 10 "vmla.f32 q7, q8, %e14[0] \n" - "vmla.f32 q13, q9, %e14[1] \n" + "vmul.f32 q13, q9, %e14[1] \n" "pld [%3, #256] \n" - "vmla.f32 q14, q12, %f14[0] \n" - "vmla.f32 q15, q11, %f14[1] \n" + "vmul.f32 q14, q12, %f14[0] \n" + "vmul.f32 q15, q11, %f14[1] \n" "vmla.f32 q7, q10, %e15[0] \n" "vld2.f32 {d16-d19}, [%3]! \n" @@ -1123,8 +1122,8 @@ static void conv5x5s2_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "vadd.f32 q14, q14, q15 \n" "vadd.f32 q7, q7, q13 \n" - "veor q15, q15 \n"// _sump3 = 0; - "veor q13, q13 \n"// _sump2 = 0; +// "veor q15, q15 \n"// _sump3 = 0; +// "veor q13, q13 \n"// _sump2 = 0; "pld [%2, #256] \n" @@ -1132,7 +1131,7 @@ static void conv5x5s2_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "vld2.f32 {d20-d23}, [%2] \n"// q10 = 8 10 12 14 q11 = 9 11 13 15 - "veor q14, q14 \n"// _sump3 = 0; +// "veor q14, q14 \n"// _sump3 = 0; "vst1.f32 {d14-d15}, [%1]! \n" diff --git a/src/layer/arm/convolution_7x7.h b/src/layer/arm/convolution_7x7.h index 7c018b1b3..c8bf53224 100644 --- a/src/layer/arm/convolution_7x7.h +++ b/src/layer/arm/convolution_7x7.h @@ -241,9 +241,9 @@ static void conv7x7s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "pld [%1, #256] \n" "vld1.f32 {d24-d25}, [%1] \n"// _sum - "veor q13, q13 \n"// _sum2 = 0; - "veor q14, q14 \n"// _sum3 = 0; - "veor q15, q15 \n"// _sum4 = 0; +// "veor q13, q13 \n"// _sum2 = 0; +// "veor q14, q14 \n"// _sum3 = 0; +// "veor q15, q15 \n"// _sum4 = 0; "pld [%9, #256] \n" "vld1.f32 {d8-d11}, [%9] \n"// q4 q5 = k0123 k4567 @@ -255,12 +255,12 @@ static void conv7x7s1_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "pld [%2, #256] \n" "vld1.f32 {d4-d7}, [%2] \n"// q2 = 4 5 6 7 q3 = 8 9 10 11 - "vmla.f32 q13, q2, d10[0] \n" + "vmul.f32 q13, q2, d10[0] \n" "vext.32 q1, q0, q2, #1 \n"// q1 = 1 2 3 4 "vext.32 q10, q2, q3, #1 \n"// q10= 5 6 7 8 - "vmla.f32 q14, q1, d8[1] \n" - "vmla.f32 q15, q10, d10[1] \n" + "vmul.f32 q14, q1, d8[1] \n" + "vmul.f32 q15, q10, d10[1] \n" "vext.32 q8, q0, q2, #2 \n"// q8 = 2 3 4 5 "vext.32 q11, q2, q3, #2 \n"// q11= 6 7 8 9 @@ -788,8 +788,8 @@ static void conv7x7s2_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "pld [%1, #256] \n" "vld1.f32 {d26-d27}, [%1] \n"// _sum - "veor q14, q14 \n"// _sum2 = 0; - "veor q15, q15 \n"// _sum3 = 0; +// "veor q14, q14 \n"// _sum2 = 0; +// "veor q15, q15 \n"// _sum3 = 0; "pld [%9, #256] \n" "vld1.f32 {d8-d11}, [%9] \n"// q4 q5 = k0123 k4567 @@ -798,12 +798,12 @@ static void conv7x7s2_neon(const Mat& bottom_blob, Mat& top_blob, const Mat& _ke "pld [%2, #512] \n" "vld2.f32 {d0-d3}, [%2]! \n"// q0 = 0 2 4 6 q1 = 1 3 5 7 "vmla.f32 q13, q0, d8[0] \n" - "vmla.f32 q14, q1, d8[1] \n" + "vmul.f32 q14, q1, d8[1] \n" "vld2.f32 {d4-d7}, [%2] \n"// q2 = 8 10 12 14 q3 = 9 11 13 15 "vext.32 q8, q0, q2, #1 \n"// q8 = 2 4 6 8 "vext.32 q9, q1, q3, #1 \n"// q9 = 3 5 7 9 - "vmla.f32 q15, q8, d9[0] \n" + "vmul.f32 q15, q8, d9[0] \n" "vmla.f32 q13, q9, d9[1] \n" "vext.32 q10, q0, q2, #2 \n"// q10= 4 6 8 10