void xcorr_kernel_neon_fixed(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)
{ int j;
int32x4_t a = vld1q_s32(sum); /* Load y[0...3] */ /* This requires len>0 to always be valid (which we assert in the C code). */
int16x4_t y0 = vld1_s16(y);
y += 4;
/* This loop loads one y value more than we actually need. Thereforewehavetostopassoonasthereare8orfewersamplesleft
(instead of 7), to avoid reading past the end of the array. */ for (j = 0; j + 8 < len; j += 8)
{ /* Load x[0...7] */
int16x8_t xx = vld1q_s16(x);
int16x4_t x0 = vget_low_s16(xx);
int16x4_t x4 = vget_high_s16(xx); /* Load y[4...11] */
int16x8_t yy = vld1q_s16(y);
int16x4_t y4 = vget_low_s16(yy);
int16x4_t y8 = vget_high_s16(yy);
int32x4_t a0 = vmlal_lane_s16(a, y0, x0, 0);
int32x4_t a1 = vmlal_lane_s16(a0, y4, x4, 0);
y0 = y8;
a = a7;
x += 8;
y += 8;
} if (j + 4 < len) { /* Load x[0...3] */
int16x4_t x0 = vld1_s16(x); /* Load y[4...7] */
int16x4_t y4 = vld1_s16(y);
int32x4_t a0 = vmlal_lane_s16(a, y0, x0, 0);
int16x4_t y1 = vext_s16(y0, y4, 1);
int32x4_t a1 = vmlal_lane_s16(a0, y1, x0, 1);
int16x4_t y2 = vext_s16(y0, y4, 2);
int32x4_t a2 = vmlal_lane_s16(a1, y2, x0, 2);
int16x4_t y3 = vext_s16(y0, y4, 3);
int32x4_t a3 = vmlal_lane_s16(a2, y3, x0, 3);
y0 = y4;
a = a3;
x += 4;
y += 4;
j += 4;
} if (j + 2 < len) { /* Load x[0...1] */
int16x4x2_t xx = vld2_dup_s16(x);
int16x4_t x0 = xx.val[0];
int16x4_t x1 = xx.val[1]; /* Load y[4...5]. Wewouldliketousevld1_dup_s32(),butcastingthepointerwould breakstrictaliasingrulesandpotentiallyhavealignmentissues. Fortunatelythecompilerseemscapableoftranslatingthismemcpy()
and vdup_n_s32() into the equivalent vld1_dup_s32().*/
int32_t yy;
memcpy(&yy, y, sizeof(yy));
int16x4_t y4 = vreinterpret_s16_s32(vdup_n_s32(yy));
int32x4_t a0 = vmlal_s16(a, y0, x0);
int16x4_t y1 = vext_s16(y0, y4, 1); /* Replace bottom copy of {y[5], y[4]} in y4 with {y[3], y[2]} from y0, usingVSRIinsteadofVEXT,sinceit'sadata-processing
instruction. */
y0 = vreinterpret_s16_s64(vsri_n_s64(vreinterpret_s64_s16(y4),
vreinterpret_s64_s16(y0), 32));
int32x4_t a1 = vmlal_s16(a0, y1, x1);
a = a1;
x += 2;
y += 2;
j += 2;
} if (j + 1 < len) { /* Load next x. */
int16x4_t x0 = vld1_dup_s16(x);
int32x4_t a0 = vmlal_s16(a, y0, x0); /* Load last y. */
int16x4_t y4 = vld1_dup_s16(y);
y0 = vreinterpret_s16_s64(vsri_n_s64(vreinterpret_s64_s16(y4),
vreinterpret_s64_s16(y0), 16));
a = a0;
x++;
} /* Load last x. */
int16x4_t x0 = vld1_dup_s16(x);
int32x4_t a0 = vmlal_s16(a, y0, x0);
vst1q_s32(sum, a0);
}
#else
#ifdefined(__ARM_FEATURE_FMA) && defined(__ARM_ARCH_ISA_A64) /* If we can, force the compiler to use an FMA instruction rather than break
* vmlaq_f32() into fmul/fadd. */ #ifdef vmlaq_lane_f32 #undef vmlaq_lane_f32 #endif #define vmlaq_lane_f32(a,b,c,lane) vfmaq_lane_f32(a,b,c,lane) #endif
/* Consume 8 elements in x vector and 12 elements in y *vector.However,the12'thelementneverreallygets *touchedinthisloop.So,iflen==8,thenweonly *mustaccessy[0]toy[10].y[11]mustnotbeaccessed *hencemakesurelen>8andnotlen>=8
*/ while (len > 8) {
yi += 4;
YY[1] = vld1q_f32(yi);
yi += 4;
YY[2] = vld1q_f32(yi);
XX[0] = vld1q_f32(xi);
xi += 4;
XX[1] = vld1q_f32(xi);
xi += 4;
/* Consume 4 elements in x vector and 8 elements in y *vector.However,the8'thelementinyneverreallygets *touchedinthisloop.So,iflen==4,thenweonly *mustaccessy[0]toy[6].y[7]mustnotbeaccessed *hencemakesurelen>4andnotlen>=4
*/ if (len > 4) {
yi += 4;
YY[1] = vld1q_f32(yi);
void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch, int arch) { int i;
(void)arch;
celt_assert(max_pitch > 0);
celt_sig_assert((((size_t)_x)&3)==0);
for (i = 0; i < (max_pitch-3); i += 4) {
xcorr_kernel_neon_float((const float32_t *)_x, (const float32_t *)_y+i,
(float32_t *)xcorr+i, len);
}
/* In case max_pitch isn't a multiple of 4, do non-unrolled version. */ for (; i < max_pitch; i++) {
xcorr[i] = celt_inner_prod_neon(_x, _y+i, len);
}
} #endif
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-10-01)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.