docs: the sample budget in samples per signal, the memory limit and the planner probe lines
Converts every --buffer-mb / buffer_mb mention to --buffer-samples / buffer_samples, records the unit change as a deviation (README, SPECS, CLAUDE.md), documents the buffer: and planner: dump lines and the new Preferences row, and updates the help pages and the help-shot script. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
034c82f7d7
commit
1627abcd4a
19 files changed
+166
-93
No files matched your search
+15
-15
@@ -46,7 +46,7 @@ when only `src/` changed, so its `-Woverlength-strings` does not reappear.
|
||||
A third reading every run offers for free: **how many `[udpscope] buffer allocated:` lines it
|
||||
printed.** The line is not behind a probe — it is in every build — and one line is one *real* change
|
||||
of buffer plan, each of which blocks the main thread for the time it takes to touch the whole
|
||||
`--buffer-mb`. A normal run prints two or three. Fifteen at startup is the defect it was added for;
|
||||
planned buffer. A normal run prints two or three. Fifteen at startup is the defect it was added for;
|
||||
see [probe-readings.md](probe-readings.md).
|
||||
|
||||
That second baseline used to be "exactly two, `gtk_widget_get_height` and `gtk_widget_get_width`,
|
||||
@@ -342,7 +342,7 @@ precedent, not an exception.
|
||||
*tick*, one frame after the ask: a `g_timeout` was the first version and it drifted past the
|
||||
paused/resumed boundary under load. The probe then asks for a **zoom-out** ten times the current span and reports
|
||||
the span the next frame produced: **`limited` must be 1**, i.e. `span <= window`. Run it with
|
||||
a ring that holds *more* than the window (`--buffer-mb 64` past the window's own seconds) —
|
||||
a ring that holds *more* than the window (`--buffer-samples 2M` past the window's own seconds) —
|
||||
that is the state the old `max(retained, window_s_)` bound leaked in, and it showed up here as
|
||||
`span=2.502550 window=2.000000 limited=0` against `span=2.000000` after the fix.
|
||||
|
||||
@@ -617,7 +617,7 @@ as distinct from the fault injection below, which exercises ingest:
|
||||
`Gain` graph over the mock's sine, waits for the ring to **saturate**, and only then edits the gain,
|
||||
which is the one state `UDPSCOPE_PROBE_MATH_MS` cannot reach (each of its edits follows a structural
|
||||
change, and a replan restarts every ring at absolute 0). It therefore needs a **small buffer and a long
|
||||
run**: `--buffer-mb 1` against `--rate 20000 --batch 200`, with
|
||||
run**: `--buffer-samples 65536` against `--rate 20000 --batch 200`, with
|
||||
`UDPSCOPE_PROBE_MATHWRAP_MS=1500 UDPSCOPE_EXIT_AFTER_MS=25000`. `base > 0` on its second line is the
|
||||
precondition — **`base=0` means the run tested nothing** — and the third line's `produced == slots` and
|
||||
`y=±0.5` are the two assertions; both are in [probe-readings.md](probe-readings.md).
|
||||
@@ -625,7 +625,7 @@ as distinct from the fault injection below, which exercises ingest:
|
||||
note, through `save_configuration_as()` (the same entry point the dialog's button uses), then
|
||||
reads it back off disk. Reading: `save-as=1`; `names=` gains `probe`; `active=probe`; and the
|
||||
round trip must carry the note **and** the startup settings —
|
||||
`comment='written by the configs probe' buffer_mb=8 relative=0 capture=0`. A `buffer_mb=0` there
|
||||
`comment='written by the configs probe' buffer_samples=10000000 relative=0 capture=0`. A `buffer_samples=0` there
|
||||
is the per-source buffer size not being written, which is the one setting a user notices only
|
||||
after a capture has been sized wrong. Run it with a throwaway `XDG_CONFIG_HOME`; the probe
|
||||
deletes its own configuration at the end (`after forget names=…`).
|
||||
@@ -681,9 +681,9 @@ as distinct from the fault injection below, which exercises ingest:
|
||||
`[defaults] calibrated: 2.5 -1.25 model=2.5 -1.25` — **the dialog must show the signal's stored
|
||||
calibration**, and the two halves must match.
|
||||
- The **chooser**, display-free: `UDPSCOPE_PROBE_SOURCES=1` prints `[sources] N known:` with one
|
||||
entry per configuration (`host:port/name … buffer= relative= note='…'`), and
|
||||
entry per configuration (`host:port/name … samples= relative= note='…'`), and
|
||||
`UDPSCOPE_PROBE_PICK_MS=800` opens the chooser, picks the first row and prints
|
||||
`[sources] picked host:port … buffer=64 relative=0 capture=0 config=… note='…'` — the settings the
|
||||
`[sources] picked host:port … samples=2097152 relative=0 capture=0 config=… note='…'` — the settings the
|
||||
configuration carried, into the `Config` the model is built from. **With no `--server` and no probe
|
||||
the chooser blocks in its own nested loop** (no frame to end and no dump), so a chooser run is
|
||||
always this probe. It also prints the dialog's frame *and its own help layer*:
|
||||
@@ -764,7 +764,7 @@ as distinct from the fault injection below, which exercises ingest:
|
||||
python3 -c "import numpy as np; n=1000000; t=-4.0+np.arange(n)/50000.0; \
|
||||
a=np.zeros(n, dtype=[('time','<f8'),('abs_seconds','<f8'),('a','<f4'),('b','<f4'),('c','<f4'),('d','<f4')]); \
|
||||
a['time']=t; a['abs_seconds']=1000.0+t; a['d']=np.linspace(-1,1,n); np.save('/tmp/long.npy', a)"
|
||||
xvfb-run -a env UDPSCOPE_EXIT_AFTER_MS=4000 ./build/udpscope --open /tmp/long.npy --buffer-mb 1
|
||||
xvfb-run -a env UDPSCOPE_EXIT_AFTER_MS=4000 ./build/udpscope --open /tmp/long.npy --buffer-samples 32768
|
||||
```
|
||||
must read `samples=31250 rows=1000000 decim=32 span=19.999980s time=[-4.000000..15.999980]` and
|
||||
`stored=31250 … published=31250` per channel — **the whole span, at a thirty-second of the rate**.
|
||||
@@ -797,21 +797,21 @@ as distinct from the fault injection below, which exercises ingest:
|
||||
the field the file dialog's callback sets and prints `[sources] picked waveform <path>` — then the
|
||||
load line above, with no socket involved.
|
||||
- **A `--server` launch reads the stored configuration.** With a throwaway `XDG_CONFIG_HOME`
|
||||
holding `127.0.0.1_8101/bench.toml` (`buffer_mb = 64`, `relative_time = true`,
|
||||
holding `127.0.0.1_8101/bench.toml` (`buffer_samples = 2097152`, `relative_time = true`,
|
||||
`capture_packets = 500`, `active` = `bench`), `./build/udpscope --server 127.0.0.1 --port 8101`
|
||||
must print `[sources] settings from configuration 'bench': buffer=64 relative=1 capture=500`, the
|
||||
`relative time:` line, and a `span=` of about 209 s (64 MB at 10 kS/s) — **not** the 200 MB
|
||||
default's ~655 s. The same command with `--buffer-mb 8` must read `buffer=8` and `span=26.214s`:
|
||||
must print `[sources] settings from configuration 'bench': samples=2097152 relative=1 capture=500`, the
|
||||
`relative time:` line, and a `span=` of about 209 s (2 097 152 ticks at 10 kS/s) — **not** the 10M default's ~839 s. The same command with
|
||||
`--buffer-samples 262144` must read `samples=262144` and `span=26.214s`:
|
||||
**an explicit flag wins over the file**. Without this, the settings a host was edited to have were
|
||||
ignored whenever the address came from the command line.
|
||||
- The chooser's **form**, with `UDPSCOPE_PROBE_PICK_MS` scheduling it:
|
||||
`UDPSCOPE_PROBE_NEWHOST=host:port` fills it and prints
|
||||
`[sources] form: name='probe-host' note='…' buffer=32 relative=1 connect_sensitive=1`, then
|
||||
`[sources] configuration created: host:port/probe-host … buffer=32 relative=1` and a
|
||||
`[sources] form: name='probe-host' note='…' samples_m=0.5 relative=1 connect_sensitive=1`, then
|
||||
`[sources] configuration created: host:port/probe-host … samples=500000 relative=1` and a
|
||||
`picked … config=probe-host`; a following `UDPSCOPE_PROBE_SOURCES=1` must list it
|
||||
(`buffer=32 relative=1 note='…'`) — a configuration the form wrote that the chooser does not
|
||||
(`samples=500000 relative=1 note='…'`) — a configuration the form wrote that the chooser does not
|
||||
list cannot be edited next time. `UDPSCOPE_PROBE_EDITHOST=host:port` opens the same form on that
|
||||
configuration and prints `[sources] edit form: name='…' note='…' buffer=… relative=… button='Save'`
|
||||
configuration and prints `[sources] edit form: name='…' note='…' samples_m=… relative=… button='Save'`
|
||||
— **the pre-fill is the assertion**: an edit form that opens empty cannot edit anything — then
|
||||
saves and reports the new values. `UDPSCOPE_PROBE_EDITNAME=new-name` renames it as well: one
|
||||
`known:` row afterwards, with the old file gone.
|
||||
|
||||
Reference in new issue
Block a user