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 <noreply@anthropic.com>
This commit is contained in:
Uladzimir Karpenka
2026-07-10 00:13:27 +03:00
parent 12dc701604
commit 91df5b1f2d
+9 -5
View File
@@ -67,11 +67,15 @@ void calc_varsamp (VARSAMP a)
line. Transposing makes each phase contiguous; hshift() interpolates line. Transposing makes each phase contiguous; hshift() interpolates
between phases hidx and hidx+1, hence R+1 of them. */ between phases hidx and hidx+1, hence R+1 of them. */
int p, m; 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); const int R = a->R, rsize = a->rsize;
a->hp = (double *)malloc0 ((size_t)(a->R + 1) * a->rsize * sizeof (double)); double* h = fir_bandpass(a->ncoef, fc_norm_low, fc_norm_high, (double)R, 1, 0, (double)R * a->gain);
for (p = 0; p <= a->R; p++) // every element is written below, so skip malloc0()'s memset of ~1 MB
for (m = 0; m < a->rsize; m++) a->hp = (double *)_aligned_malloc ((size_t)(R + 1) * rsize * sizeof (double), 16);
a->hp[(size_t)p * a->rsize + m] = h[p + (size_t)m * a->R]; // 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); _aligned_free (h);
} }
a->ringI = (double *)malloc0(a->rsize * sizeof(double)); a->ringI = (double *)malloc0(a->rsize * sizeof(double));