Feed bitwise collectors straight into the histogram; cut reduce allocations#793
Conversation
…ations - Collectors now take &mut BitwiseHistogram instead of returning Vec<BitwiseOperation>. The heavy sources count with no per-source vector at all: MEMW_R bumps one IS_HALFWORD per row (tens of millions of rows), PAGE bumps one ARE_BYTES per byte of every touched page, and CPU padding collapses to two bump_n calls instead of an O(padding_rows) vector of identical zero ops. - reduce_with replaces reduce(identity, ..) in the rayon tree-reduce, eliminating one zeroed 80 MiB identity histogram per reduce leaf. - RegRow.address shrinks to u16 (register index 0..=255), taking the largest persisted array of the walk from 40 to 32 bytes per row.
19b75b4 to
1287123
Compare
55bbe35 to
47948a2
Compare
|
Rebased and composed with 3ba4aac: kept its |
|
/bench |
Benchmark — ethrex 20 transfers (median of 3)Table parallelism: auto (cores / 3)
Commit: 47948a2 · Baseline: cached · Runner: self-hosted bench |
The bitwise-histogram comments were phrased against the pre-refactor code
("byte-identical to the previous serial .extend() chain", "instead of an
O(n) op vector") — narration that is meaningless once this merges and the
old path is gone. Restate them as standalone rationale: the multiplicities
are order-independent (permutation-invariant bus) so parallel collection is
sound, and the reduce_with note now explains why to prefer it over
reduce(identity) rather than referencing a removed path. Also fix the stale
add_padding_byte_checks doc (it described the pre-shrink 14-op CPU layout).
Repo-wide sweep of the trace-generation code for comments that narrate a
change the next reader can't see, or that contradict the code:
- MemwBuckets doc and collect_all_ops no longer reference "the old two-stage
partition" / "byte-identical to partition-ing one combined vec" — that
partition sweep no longer exists anywhere (grep '.partition(' → 0 hits).
Restated as the current invariant (register-first-then-aligned, deterministic
insertion order the multiplicity counts rely on).
- Fix the MEMW_R ADDRESS column doc: register index range is 0-255 (x0-x31 plus
the x254 commit index and x255 PC), not 0-31.
The Bus-14 comment in collect_store_op_from_cpu said the packed value "must match CPU M7 which sends full rv2 as [lo32, hi32]", but M7 (the CPU's old inline store MEMW at timestamp+1) was removed in the ALU-bus migration. The store value now flows CPU -> MEMORY/MEMOP (rv2 as [lo32, hi32]) -> STORE chip -> MEMW write. Reword to describe that path; the byte-layout requirement it gestured at is unchanged.
Final follow-up from the #786 review, stacked on #792. Applies the PR's own "never materialize a Vec whose only consumer is the multiplicity count" principle to the remaining big sources, and removes the rayon reduce-identity allocations. Multiplicities are unchanged (same counts, same cells).
Changes
BitwiseHistogramdirectly (Fn(&mut BitwiseHistogram)) instead of returningVec<BitwiseOperation>:bump_ncalls (3n ARE_BYTES[0,0] + 4n IS_HALF[0,0]) instead of an O(padding_rows) vector of identical zero ops (which also over-reserved 2×).collect_*functions; the closure folds the transient Vec in and drops it.reduce_withreplacesreduce(identity, ..)in the rayon tree-reduce: no more zeroed 80 MiB identity histogram per reduce leaf (up to ~16 × 80 MiB of pure alloc_zeroed + merge traffic on many-core machines).RegRow.addressshrinks to u16 (register index 0..=255): the walk's largest persisted array goes from 40 to 32 B/row.Measurements
Local tests
cargo build --release --features instruments,cli prove --time, Apple Silicon, best of 2 runs, this branch vs its base (#792):prove_totaland peak RSS unchanged within run-to-run noise on this machine (p4 is <1% of total here, and macOS RSS jitters ~1.5 GB between runs). The reduce-identity savings scale with core count, so the effect should be larger on the many-core provers #786 targets. The remaining serialbase.add_opsover the in-walk lookups was left as-is: parallelizing it adds code for a phase already down to ~85 ms.Server
Testing
cargo test -p lambda-vm-prover --libon this change: 503 passed (same 5 known missing-fixture failures, which fail at file-read).make lintpasses; clippy--all-targetsno warnings; fmt clean.