ref: 4e018b22bb1594daccb29cd6e92cca11809111d2
parent: 39cbc45828cdbb2a74e4bea44a399e3a5b0a4530
author: Jean-Marc Valin <[email protected]>
date: Thu Jun 13 19:51:58 EDT 2013
SSE optimization of remove_doubling() Should be trivial to adapt for Neon.
--- a/celt/pitch.c
+++ b/celt/pitch.c
@@ -394,6 +394,20 @@
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 @@
{
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
{
--- a/celt/x86/pitch_sse.h
+++ b/celt/x86/pitch_sse.h
@@ -71,4 +71,34 @@
_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