From 4e018b22bb1594daccb29cd6e92cca11809111d2 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jmvalin@jmvalin.ca> Date: Thu, 13 Jun 2013 23:51:58 -0400 Subject: [PATCH] SSE optimization of remove_doubling() Should be trivial to adapt for Neon. --- celt/pitch.c | 21 +++++++++++++++------ celt/x86/pitch_sse.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/celt/pitch.c b/celt/pitch.c index f8115c2fe..025f448de 100644 --- a/celt/pitch.c +++ b/celt/pitch.c @@ -394,6 +394,20 @@ void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTR RESTORE_STACK; } +#ifndef OVERRIDE_DUAL_INNER_PROD +static opus_val32 dual_inner_prod(opus_val16 *x, opus_val16 *y1, opus_val16 *y2, int N) +{ + int i; + opus_val32 xy=0; + for (i=0;i<N;i++) + { + xy = MAC16_16(xy, x[i], y1[i]); + xy = MAC16_16(xy, x[i], y2[i]); + } + return xy; +} +#endif + static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2}; opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, int N, int *T0_, int prev_period, opus_val16 prev_gain) @@ -470,12 +484,7 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, { T1b = (2*second_check[k]*T0+k)/(2*k); } - xy=0; - for (i=0;i<N;i++) - { - xy = MAC16_16(xy, x[i], x[i-T1]); - xy = MAC16_16(xy, x[i], x[i-T1b]); - } + xy = dual_inner_prod(x, &x[-T1], &x[-T1b], N); yy = yy_lookup[T1] + yy_lookup[T1b]; #ifdef FIXED_POINT { diff --git a/celt/x86/pitch_sse.h b/celt/x86/pitch_sse.h index a55a69b73..4512665c0 100644 --- a/celt/x86/pitch_sse.h +++ b/celt/x86/pitch_sse.h @@ -71,4 +71,34 @@ static inline void xcorr_kernel(const opus_val16 *x, const opus_val16 *y, opus_v _mm_storeu_ps(sum,_mm_add_ps(xsum1,xsum2)); } +#define OVERRIDE_DUAL_INNER_PROD +static inline opus_val32 dual_inner_prod(const opus_val16 *x, const opus_val16 *y1, const opus_val16 *y2, int N) +{ + int i; + __m128 xsum1, xsum2; + opus_val32 xy=0; + xsum1 = _mm_setzero_ps(); + xsum2 = _mm_setzero_ps(); + for (i=0;i<N-3;i+=4) + { + __m128 xi = _mm_loadu_ps(x+i); + __m128 y1i = _mm_loadu_ps(y1+i); + __m128 y2i = _mm_loadu_ps(y2+i); + xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(xi, y1i)); + xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(xi, y2i)); + } + xsum1 = _mm_add_ps(xsum1,xsum2); + /* Horizontal sum */ + xsum1 = _mm_add_ps(xsum1, _mm_movehl_ps(xsum1, xsum1)); + xsum1 = _mm_add_ss(xsum1, _mm_shuffle_ps(xsum1, xsum1, 0x55)); + _mm_store_ss(&xy, xsum1); + for (;i<N;i++) + { + xy = MAC16_16(xy, x[i], y1[i]); + xy = MAC16_16(xy, x[i], y2[i]); + } + return xy; +} + + #endif -- GitLab