Skip to content

perf(trie): batch fixed-base multiplications over smaller tables - #165

Open
flyq wants to merge 4 commits into
liquan/perf/compact-witness-storagefrom
liquan/perf/batched-trie-commitment
Open

flyq wants to merge 4 commits into
liquan/perf/compact-witness-storagefrom
liquan/perf/batched-trie-commitment

Conversation

@flyq

@flyq flyq commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Ports PR #4 of suryuhh/salt-optimizations (commit e7e1e43): the committer's fixed-base multiplications, eight per vector register, over smaller tables.

  • Committer::mul_index_batch is new. On a host with AVX-512 IFMA it runs eight multiplications per register; elsewhere it maps mul_index.
  • The trie update issues its multiplications per chunk through it.
  • On a host with IFMA the shared committer is built at window 7 instead of 11. The external commit gives 39.4 MB of table data for 256 bases at window 7, against 403 MB at window 11.

Hosts without IFMA keep window 11 and the scalar path.

Stacked on the compact storage PR (liquan/perf/compact-witness-storage). Last of the four.

Changes on top of the external commit

  • msm and msm_dense run in lanes too. At window 7 one mul_index is 37 additions instead of 24. The external change moved the trie update to the batch, but Committer::msm and msm_dense still multiplied one scalar at a time. Proof creation (the IPA rounds, the dense polynomial commitment) and the node-polynomial cache's admission check go through those two, so each would have slowed by about half on IFMA hosts. Each thread's terms now go through mul_index_batch there, in tasks of whole lane groups. Hosts without lanes keep the scalar loop as it was.
  • The IPA's blinding term joins the round's msm. It was a lone mul_index per side per round.
  • The shared committer keeps the G ++ [Q] tables of perf: faster witness proofs and proof checks #152. The only cherry-pick conflict: DEFAULT_CRS.committer(platform::precomp_window_size()).
  • The table point layout is asserted. mul_index8 gathers x at +0 and y at +32 of an EdwardsAffine; a different layout now fails to compile.
  • Window 7 is in the default equivalence test. It was only checked by an ignored bench.
  • Four line-pinned suppressions in trie.rs are re-pinned (905/911/914/916 to 912/918/921/923). The code at those sites did not change.

Testing

Passing on this head, on an Apple Silicon machine:

  • cargo fmt --all -- --check; cargo clippy --all-targets -- -D warnings, native and --target x86_64-unknown-linux-gnu
  • cargo test; with test-bucket-resize (CI's settings); the random stress test; --no-default-features with and without test-bucket-resize
  • cargo check -p salt --target riscv64imac-unknown-none-elf --no-default-features
  • cargo check --all-targets --target i686-unknown-linux-gnu
  • cargo-mutants on the diff: 8 of 8 viable mutants killed, 2 unviable. Spec-gate: 1 of 1 killed. Suppression hygiene passes.
  • stateless-validator main (c46a541): cargo check --workspace --all-targets with its salt dependency patched to this head.

New tests run on every host: mul_index_batch against mul_index at windows 11 and 7, the batched sum against the scalar sum and the reference MSM, and the task size. create_with_precomp_matches_create covers the blinding term.

Not run:

  • Any AVX-512 path, including the lane msm above. No such CPU or emulator on the machine used; compiled and linted for x86_64 only. On a host without lanes the new tests only exercise the scalar fallback of mul_index_batch. The Test Suite (AVX-512 IFMA) job is their first real execution.
  • Benchmarks. The claim that proof creation does not regress at window 7 is by construction, not measured. perf-regression runs update 10000 KVs on a runner with IFMA, so the trie update number arrives with this PR. salt/benches/proof.rs (witness creation) is not covered by it and needs a run on a host with IFMA against main.
  • mega-reth against this head.
  • The i686 test job.

Merging

Please keep this trailer in the squash message:

Co-authored-by: suryuhh <suryuhh@users.noreply.github.com>

🤖 Generated with Claude Code

suryuhh and others added 4 commits November 14, 2026 15:04
(cherry picked from commit e7e1e43958802e67c0d1417ab114f964a3a9b0b7)
…er gathers from

mul_index8 gathers a table point's x at +0 and y at +32. Nothing fixed
that layout, so a change in ark's Affine would have read the wrong words
without a compile error; assert it, as ifma_normalize does.

The production window (LANE_PRECOMP_WINDOW_SIZE) was only checked by the
ignored bench; add it to lane_mul_index_matches_scalar.

words_to_limbs now comes from the shared IFMA module, so the copy here
goes.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
On a host with AVX-512 IFMA the shared committer is now built at window
7, where one mul_index is 37 additions instead of 24. The trie update
went to mul_index_batch with that change, but msm and msm_dense still
multiplied one scalar at a time, so proof creation (the IPA rounds, the
dense polynomial commitment) and the node-polynomial cache's admission
check would each have slowed by about half on those hosts.

Send each thread's terms through mul_index_batch there, in tasks of whole
lane groups. Hosts without lanes keep the scalar loop unchanged.

The IPA's blinding term was a lone mul_index per side per round; make it
one more term of the round's msm.

Not measured: needs a host with AVX-512 IFMA (salt/benches/proof.rs).

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Issuing the trie update's multiplications per chunk added seven lines
above create_node_aligned_chunks, moving its four pinned loop sites
without changing them (trie.rs 905/911/914/916 -> 912/918/921/923). Same
code, same mutants, so the existing justifications still hold.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Mutation testing - PASS

Mutation score: 100.0% (1/1 viable mutants killed)

  • caught: 1
  • survived, real gaps: 0
  • timed out, inconclusive: 0
  • suppressed: 0
  • unviable: 0
  • timeout total: 0

No unsuppressed survivors or timeouts remain.

@github-actions

Copy link
Copy Markdown

Performance Benchmark Comparison

Compared 5 benchmark(s) against the latest main baseline.

Detailed Comparison
Benchmark Baseline Throughput (Kelem/s) New Throughput (Kelem/s) Change
update 10000 KVs/1 threads 83.52 174.16 +108.53%
update 10000 KVs/2 threads 160.32 323.25 +101.63%
update 10000 KVs/4 threads 299.94 539.85 +79.99%
update 10000 KVs/8 threads 490.69 804.66 +63.99%
update 10000 KVs/16 threads 617.42 916.97 +48.52%

@github-actions

Copy link
Copy Markdown

Mutation testing - PASS

Mutation score: 100.0% (6/6 viable mutants killed)

  • caught: 6
  • survived, real gaps: 0
  • timed out, inconclusive: 0
  • suppressed: 0
  • unviable: 4
  • timeout total: 0

No unsuppressed survivors or timeouts remain.

@codecov

codecov Bot commented Nov 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.64984% with 55 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
banderwagon/src/ifma_committer.rs 77.41% 34 Missing and 1 partial ⚠️
banderwagon/src/salt_committer.rs 85.34% 13 Missing and 4 partials ⚠️
banderwagon/src/platform.rs 50.00% 2 Missing and 1 partial ⚠️
Files with missing lines Coverage Δ
banderwagon/src/lib.rs 70.00% <ø> (ø)
ipa-multipoint/src/ipa.rs 99.39% <100.00%> (+<0.01%) ⬆️
salt/src/trie/trie.rs 98.22% <100.00%> (+0.01%) ⬆️
banderwagon/src/platform.rs 50.00% <50.00%> (ø)
banderwagon/src/salt_committer.rs 93.07% <85.34%> (-4.45%) ⬇️
banderwagon/src/ifma_committer.rs 77.41% <77.41%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants