From 91df5b1f2daf39e01f133098b7588929819a563c Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Fri, 10 Jul 2026 00:13:27 +0300 Subject: [PATCH] varsamp: build the phase table without malloc0's memset, read h forward calc_varsamp() gained a transpose of the coefficient table, which showed up as ~0.3 ms on create_varsamp()/setInRate_varsamp() (1.0 ms -> 1.4 ms). It is a one-off setup cost, not on the sample path, but it is easy to trim: every element of hp is written, so malloc0()'s memset of ~1 MB is dead, and h is cold straight out of fir_bandpass(), so walk it along its fast axis and let the prefetcher work. Output is bit-identical; xvarsamp() is unchanged at ~34 us/buffer. Co-Authored-By: Claude Opus 4.8 --- varsamp.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/varsamp.c b/varsamp.c index aeef36e..db0dec0 100644 --- a/varsamp.c +++ b/varsamp.c @@ -67,11 +67,15 @@ void calc_varsamp (VARSAMP a) line. Transposing makes each phase contiguous; hshift() interpolates between phases hidx and hidx+1, hence R+1 of them. */ int p, m; - double* h = fir_bandpass(a->ncoef, fc_norm_low, fc_norm_high, (double)a->R, 1, 0, (double)a->R * a->gain); - a->hp = (double *)malloc0 ((size_t)(a->R + 1) * a->rsize * sizeof (double)); - for (p = 0; p <= a->R; p++) - for (m = 0; m < a->rsize; m++) - a->hp[(size_t)p * a->rsize + m] = h[p + (size_t)m * a->R]; + const int R = a->R, rsize = a->rsize; + double* h = fir_bandpass(a->ncoef, fc_norm_low, fc_norm_high, (double)R, 1, 0, (double)R * a->gain); + // every element is written below, so skip malloc0()'s memset of ~1 MB + a->hp = (double *)_aligned_malloc ((size_t)(R + 1) * rsize * sizeof (double), 16); + // walk h forward (p is its fast axis) so the prefetcher sees a linear + // stream; h is cold here, straight from fir_bandpass() + for (m = 0; m < rsize; m++) + for (p = 0; p <= R; p++) + a->hp[(size_t)p * rsize + m] = h[p + (size_t)m * R]; _aligned_free (h); } a->ringI = (double *)malloc0(a->rsize * sizeof(double));