Perf/verifier eval points elf digest#848
Conversation
step_3 computed the primary point (pow per query) for the batch inverse, and the DEEP reconstruction recomputed both the primary and symmetric points — 3 domain exponentiations per query per table. Compute the primary points once up front and share them; the symmetric point is the primary's negation (bit-reversed indices 2i/2i+1 differ by lde_length/2, and ω^(lde_length/2) = −1), so it costs one field negation instead of a pow. The batch inverse now consumes the shared vector.
A continuation verify hashed the entire inner ELF 2E+1 times: each verify_epoch built its seeded transcript twice (bus-balance replay + multi_verify) and each build ran a full-ELF Keccak inside absorb_statement. Compute the digest once in verify_continuation and thread it through verify_epoch/verify_global via the existing absorb_*_with_digest variants (adding the global-statement one), and clone the seeded transcript for the replay instead of reseeding. The absorbed bytes are identical, so this is transcript-neutral. Prove-side epoch/global transcripts take a precomputed digest too. Guest-cycle impact: one full-ELF Keccak per bundle instead of 2E+1 (e.g. a 1 MiB ELF ≈ 7.5k permutations ≈ 10M cycles per pass at the current ~1.3k cycles/permutation sponge-glue cost).
|
/bench-verify |
|
⏳ Benchmark started on the bench server. The verifier bench takes ~5 min; the recursion-guest cycle comparison then adds guest builds — a few minutes when cached, up to ~1h on a cold run. The bench server is occupied until it finishes. |
Verifier benchmark —
|
| Metric | main | PR | Δ |
|---|---|---|---|
| Verify time | 3.583s | 3.586s | +0.10% ⚪ |
| Proof size | 204.30 MiB | 204.30 MiB | +0.00% ⚪ |
pairs: 20 mean A (PR): 3.586s mean B (main): 3.583s
[parametric] paired-t mean +0.10% sd 0.38% se 0.09%
95% CI: [-0.08%, +0.28%] (t df=19 = 2.093)
[robust] median +0.06% Wilcoxon W+=130 W-=80 p(exact)=0.3683 (z=+0.91)
run-to-run jitter: A CV 0.39% B CV 0.43% (lower = steadier)
within-session drift: -0.07% over the run, 1st->2nd half -0.07%
⚪ INCONCLUSIVE — effect not separable from 0 at n=20 (point estimate ~+0.06%). Add pairs to resolve.
Drift-free interleaved A/B/B/A measurement. - = PR faster. Trust the verdict when paired-t and Wilcoxon agree.
Recursion guest cycles (main vs PR)
=== Recursion-guest cycle comparison — single query (blowup=2, 1 query) — deterministic to ~±100k cycles ===
REF_B (baseline) origin/main 3be1eed guest=recursion-min.elf
REF_A (PR) e3c8de2 e3c8de2 guest=recursion-min.elf
| Metric | REF_B (baseline) | REF_A (PR) | Δ (A-B) |
|---|---|---|---|
| Guest cycles | 43.6M | 43.5M | -0.1M (-0.23%) |
| Keccak calls | 3025 | 3025 | 0 |
note: cycles reproduce to ~±100k (build codegen + proof nondeterminism); treat sub-100k deltas as noise, not signal.
raw (exact integer counts)
ref_b_sha=3be1eed35bd73e96c36a99bf03b58a87cf358af7 ref_b_elf=recursion-min.elf ref_b_cycles=43605029 ref_b_keccak=3025 ref_b_execute_wall_s=1
ref_a_sha=e3c8de28fa1f76bb1f3734fac6cb7c941758399f ref_a_elf=recursion-min.elf ref_a_cycles=43505290 ref_a_keccak=3025 ref_a_execute_wall_s=2
delta_cycles=-99739 delta_keccak=0
Proves one ethrex continuation bundle (real program, many epochs) and times verify --continuations on main vs the fix branch, reporting the implied per-full-ELF-hash cost from the epoch count and ELF size. bench_verify.sh cannot see this fix — it only exercises the monolithic path, which already shared one digest.
One command on the server: make bench-elf-digest (env overrides: N_PAIRS, TRANSFERS, EPOCH_LOG2, REF_A, REF_B).
|
/bench-verify |
|
⏳ Benchmark started on the bench server. The verifier bench takes ~5 min; the recursion-guest cycle comparison then adds guest builds — a few minutes when cached, up to ~1h on a cold run. The bench server is occupied until it finishes. |
Every epoch rebuilt its AIRs with decode_commitment=None, so VmAirs::new fell back to decode::commitment_from_elf — re-parsing every instruction, regenerating the DECODE trace, FFT-interpolating and LDE-evaluating each precomputed column, and Merkle-committing them (~1M Keccak hashes + the FFT batch for a 1 MiB program), byte-identical work on every epoch of both prove_continuation and verify_continuation. Compute the commitment once in the bundle drivers and thread it through prove_epoch/verify_epoch into build_epoch_airs. The recursion guest is unaffected (it already receives the root as supplied input); this is the native prove/verify path.
|
/bench-verify |
|
⏳ Benchmark started on the bench server. The verifier bench takes ~5 min; the recursion-guest cycle comparison then adds guest builds — a few minutes when cached, up to ~1h on a cold run. The bench server is occupied until it finishes. |
No description provided.