perf: the measurements pane keys its shared walks by channel and HF corner
The pane shared its two walks per *channel*, but the HF corner is a per-measurement
setting: two measurements on one signal at different corners read two different signals
and cannot share a walk. `App::MeasureWindow` therefore carries `channel` and `fc`, the
container is a vector, and the grouping loop matches on both -- keeping its dedupe of the
level accumulators by `(pct, noise)`, since a type that does not read the band must not
split an accumulator over it.
Each window carries two filters, one per walk: they are separate walks, so separate state.
A filtered window also stops using the LOD pyramid, which one `if` does -- leaving
`buckets` empty makes `bulk_from == bulk_to == n`, so the raw walk covers the window and
`lo_search`/`hi_search` stay 0, which makes the pinning pass a no-op. Nothing downstream
needs to know.
The readout loop looks its window up by index rather than by channel, which is what the
`(channel, fc)` key needs.
The documented measurement baseline is unchanged, and it is the assertion:
[measure-trace] average=0.000000 top=0.636620 peak to peak=2.000000 amplitude=1.000000
[udpscope] measure cost: ... covered=75378013 buckets=1177164 raw=159674 (0.2%)
`top` is 2/pi to the digit -- the one reading a band leaking into the sums would move --
and `raw` at 0.2 % of `covered` says the fast path is still being used on an unfiltered
window.
The measure probe now enables `sine` itself, as the noise probe does: `enable_all_probe`
ends by switching a signal off, and with `sine` gone the probe measured `square`, where
`top` is 1.0 and the baseline above is unreachable.
This commit is contained in:
1 parent
2730707372
commit
380ddb9a77
3 files changed
+79
-17
No files matched your search
+12
-2
@@ -274,13 +274,23 @@ struct App {
|
||||
/// them asked for. Several measurements on one signal must cost two walks, not two each -- and
|
||||
/// the window itself is never stored, which is what the chunked walks bought (see
|
||||
/// `MeasureChunk`).
|
||||
/// One channel's window, at one HF corner, with every level accumulator the pane asked for.
|
||||
///
|
||||
/// Keyed by `(channel, fc)` and not by channel alone: the corner is a per-measurement setting, so two
|
||||
/// measurements on one signal at different corners are reading two different signals and cannot share a
|
||||
/// walk.
|
||||
struct MeasureWindow {
|
||||
int channel = -1;
|
||||
double fc = 0.0; ///< the HF corner this window was walked at; 0 is unfiltered
|
||||
MeasureStats stats;
|
||||
std::vector<double> pct; ///< the level shares asked for, deduplicated
|
||||
std::vector<double> pct; ///< the level shares asked for, deduplicated
|
||||
std::vector<double> noise; ///< each entry's band, as a percentage; parallel to `pct`
|
||||
std::vector<MeasureLevel> level; ///< one accumulator per entry of `pct`
|
||||
MeasureFilter scan_filter; ///< pass one's state
|
||||
MeasureFilter acc_filter; ///< pass two's; a separate walk, so a separate state
|
||||
bool ok = false;
|
||||
};
|
||||
std::unordered_map<int, MeasureWindow> measure_samples;
|
||||
std::vector<MeasureWindow> measure_samples;
|
||||
/// The window's LOD buckets, reused across recomputes: a 1.7 M-sample window is 26 k of them,
|
||||
/// and both passes walk the same list.
|
||||
std::vector<MeasureBucket> measure_bucket_scratch;
|
||||
|
||||
Reference in new issue
Block a user