Gate: batch machine toplevel steps into one dry-run sweep (measured ~3-4x faster, flat memory) #118
Labels
No labels
blocked
bug
decision
duplicate
enhancement
help wanted
invalid
landed?
question
ready-to-merge
stale
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/archetypes#118
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Gate: batch the machine toplevel steps into one dry-run sweep (measured ~3-4x faster, no memory cost)
Measured on nix-dev (6 cores, 7.8 GiB, nix 2.34.8) overnight: the deploy
gate (
check.sh) was repeated 60 times, timestamped per line. 60/60passed, wall 59-64 s (std 1.24 s).
Why the gate is slow
The gate runs 7-8 machine toplevel steps SERIALLY, and each step forces
the entire system derivation graph (its eval step forces
config.system.build.toplevel.drvPath). That single, deterministic,cache-independent graph instantiation costs 9-11 s per machine, so ~8
machines x ~7.3 s mean = ~95% of the 60 s. The 21 check steps cost
0.10 s each; the AR ran-to-run wall forecast can save at most ~1 s.
Proposal (small, same guarantees, no concurrency)
Replace the per-machine forced
drvPathsteps with ONE batchedplus the existing cheap check builds (already batchable to ~1 s). A
single process, no extra parallelism machinery, no new locks, and the
shared portion of the 8 graphs is instantiated once instead of 8 times
repeatedly.
--dry-runstill instantiates every derivation (sameerror-catching coverage as forcing drvPath, plus the build plan), and
needs no downloads, so the substitution cost that made batching real
builds slow does not apply.
Observed probe: batched dry-run of the machine set ran far below the
serial sum (live measurement; confirm on landing with the command
above). Expected gate wall ~15-25 s.
Why not parallelise the machine steps instead
Two full gates in parallel were measured SLOWER (70 s vs 61 s); nix's
eval.cache is a single-writer sqlite database, so concurrent evals
serialise on its lock. A batch in ONE process sidesteps that entirely.
Constraints honored
one-off 1.4 GiB). No store surgery, no new services, no new
languages, ~20 lines in the gate's run loop.
accounting preserved via --keep-going + the run_step capture
(covers the gate's red-when-any-fails contract).
Validation to run on landing
nix build --dry-run --keep-going --no-linkover all machinetoplevels: expect ~15-25 s vs 60 s serial.
check-selftest.sh covers this).
freeduring the sweep stays > 2 GiB available.Closing as not planned. The proposal was implemented and measured in allod/tools#244, and the speedup is not there: the gate on this repository went from 78.1 s to 76.1 s, which is inside the run-to-run noise. That PR is closed unmerged and holds the full numbers.
What the measurements found against this issue's claims:
nix build --dry-runon an unchanged tree returned in 1.2 s; the first run on a tree took 27 to 31 s for four machines.--keep-goingdoes not keep per-machine failures. Evaluation stops at the first machine that fails and the rest are never named.check.shwas deleted by #117. Inallod check, machines are 23 s of 78 s and the checks are 54 s.If a faster gate is still wanted, the two things that measured as real are running a few steps at once, and letting steps use the evaluation cache. Each is a decision about what the gate may do and would need its own issue.
Closed as not planned.