Skip to content

perf(preprocessing): parallelize CPU setup passes - #1737

Merged
0xAndoroid merged 4 commits into
mainfrom
perf/preprocessing-parallel
Aug 21, 2026
Merged

0xAndoroid merged 4 commits into
mainfrom
perf/preprocessing-parallel

Conversation

@0xAndoroid

@0xAndoroid 0xAndoroid commented Aug 5, 2026 •

Copy link
Copy Markdown
Collaborator

What changed

  • Convert Cycle → TraceRow with Rayon above a 2^14-row threshold; small traces stay serial. Error capture stays out of band so indexed collection writes directly into one output allocation while preserving ordering, error propagation, and panic behavior.
  • Run ProverConfig::derive's touched-address reduction through Rayon under the existing default parallel feature; small/no-default builds stay serial.
  • Use the released crates.io dory-pcs 0.4.1. Companion perf(cache): prepare pairing points in parallel dory#30 carries the prepared-point cache portion of this optimization; Jolt no longer pins an unreleased repository commit.
  • Remove all campaign env selectors. These are unconditional defaults on the plain CPU prover path.

CPU measurements

Originating locked 2^26 campaign pair, same proof bytes:

preprocessing block serial parallel
Cycle → TraceRow 7.54 s 0.68–0.80 s
ProverConfig::derive 0.50 s 0.04 s
end-to-end elapsed 26 s 17 s
prove span 4.24 s 4.30 s (noise)

Prepared-point initialization (companion a16z/dory#30):

measurement serial parallel
campaign 2^26 prep tail 16.2 s 502 ms
Apple M4, log_n=34, 131,072 points/group 6.449 s 1.071 s median

The campaign's 2^28 traces put serial conversion at ~30–43 s and serial prepared-point initialization above 30 s.

Scope

Excluded W7 PAD_INTERLEAVE: it is implemented inside the CUDA trace-store/store-early pipeline and has no standalone plain-CPU path to upstream here.

Verification

  • workspace: 2508/2508
  • legacy muldiv, host: 3/3
  • legacy muldiv, host+zk: 3/3
  • modular fixtures: 18/18
  • modular fixtures+zk: 12/12
  • clippy -D warnings: host and host+zk
  • rustfmt; taplo; no-default-features check

Authored with Claude Code.

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

github-actions Bot commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor

Benchmark comparison (crates)

group                           main_run                               pr_run
-----                           --------                               ------
EqPolynomial::evals/17          1.00  1621.0±30.83µs        ? ?/sec    1.19  1926.4±22.52µs        ? ?/sec
EqPolynomial::evals/19          1.00      6.1±0.04ms        ? ?/sec    1.21      7.4±0.07ms        ? ?/sec
EqPolynomial::evals/20          1.00     12.9±0.13ms        ? ?/sec    1.16     15.0±0.09ms        ? ?/sec
EqPolynomial::evals/22          1.00     49.3±0.18ms        ? ?/sec    1.17     57.8±0.31ms        ? ?/sec
EqPolynomial::evaluations/14    1.00    484.8±8.26µs        ? ?/sec    1.61   782.2±21.41µs        ? ?/sec
EqPolynomial::evaluations/18    1.00      5.6±0.08ms        ? ?/sec    1.20      6.7±0.07ms        ? ?/sec
EqPolynomial::evaluations/20    1.00     23.8±0.10ms        ? ?/sec    1.19     28.3±0.20ms        ? ?/sec
Fr * Fr                         1.00     20.7±0.20ns        ? ?/sec    1.22     25.3±0.33ns        ? ?/sec
Fr::from_bytes                  1.00    128.2±1.09ns        ? ?/sec    1.23    157.1±3.27ns        ? ?/sec
Fr::mul_u128                    1.00     18.9±0.13ns        ? ?/sec    1.13     21.3±0.44ns        ? ?/sec
Fr::mul_u64                     1.00      9.3±0.08ns        ? ?/sec    1.26     11.8±0.11ns        ? ?/sec
Fr::to_bytes                    1.00     15.6±0.17ns        ? ?/sec    1.14     17.7±0.21ns        ? ?/sec
Polynomial::bind/14             1.00    118.4±2.40µs        ? ?/sec    1.10    130.3±6.69µs        ? ?/sec
Polynomial::bind/18             1.00  1689.8±26.98µs        ? ?/sec    1.15  1938.2±26.29µs        ? ?/sec
Polynomial::bind/20             1.00      6.6±0.06ms        ? ?/sec    1.17      7.7±0.07ms        ? ?/sec
Polynomial::evaluate/20         1.00     34.4±0.09ms        ? ?/sec    1.20     41.3±0.24ms        ? ?/sec
append_bytes/Blake2b/256B       1.00    275.4±4.19ns        ? ?/sec    1.24    341.5±4.38ns        ? ?/sec
append_bytes/Blake2b/32B        1.00     45.3±2.03ns        ? ?/sec    1.10     49.7±4.39ns        ? ?/sec
append_bytes/Keccak/256B        1.00    710.2±7.66ns        ? ?/sec    1.16   826.3±15.10ns        ? ?/sec
append_bytes/Keccak/32B         1.00     32.8±0.49ns        ? ?/sec    1.36     44.5±0.66ns        ? ?/sec
append_bytes/Poseidon/256B      1.00    228.1±1.45µs        ? ?/sec    1.27    290.0±3.71µs        ? ?/sec
append_bytes/Poseidon/32B       1.00     75.8±0.48µs        ? ?/sec    1.22     92.8±0.91µs        ? ?/sec
challenge/Blake2b               1.00    569.3±6.62ns        ? ?/sec    1.13    640.8±7.29ns        ? ?/sec
challenge/Keccak                1.00    341.6±3.33ns        ? ?/sec    1.16    395.8±5.12ns        ? ?/sec
challenge/Poseidon              1.00     38.1±0.23µs        ? ?/sec    1.22     46.3±0.63µs        ? ?/sec
g1_add                          1.00    358.8±2.27ns        ? ?/sec    1.14    409.3±9.29ns        ? ?/sec
g1_deserialize_bincode          1.00      7.5±0.06µs        ? ?/sec    1.23      9.2±0.12µs        ? ?/sec
g1_double                       1.00    186.1±1.72ns        ? ?/sec    1.15    214.4±1.49ns        ? ?/sec
g1_msm/1024                     1.00     10.9±0.02ms        ? ?/sec    1.17     12.8±0.25ms        ? ?/sec
g1_msm/16                       1.00    464.9±1.35µs        ? ?/sec    1.15    533.6±3.10µs        ? ?/sec
g1_msm/256                      1.00      3.7±0.01ms        ? ?/sec    1.17      4.3±0.09ms        ? ?/sec
g1_msm/4                        1.00   224.1±11.06µs        ? ?/sec    1.13    253.2±1.42µs        ? ?/sec
g1_msm/64                       1.00  1271.8±12.40µs        ? ?/sec    1.24  1572.8±18.96µs        ? ?/sec
g1_scalar_mul                   1.00     55.8±0.16µs        ? ?/sec    1.16     64.7±2.19µs        ? ?/sec
g1_serialize_bincode            1.00     93.5±1.43ns        ? ?/sec    1.18    110.4±1.04ns        ? ?/sec
g2_msm/16                       1.00  1555.5±12.95µs        ? ?/sec    1.24  1923.4±20.58µs        ? ?/sec
g2_msm/256                      1.00     13.6±0.04ms        ? ?/sec    1.14     15.5±0.05ms        ? ?/sec
g2_msm/4                        1.00    674.5±6.83µs        ? ?/sec    1.16   783.7±37.10µs        ? ?/sec
g2_msm/64                       1.00      4.9±0.02ms        ? ?/sec    1.14      5.6±0.03ms        ? ?/sec
g2_scalar_mul                   1.00    279.6±0.92µs        ? ?/sec    1.15    322.4±3.99µs        ? ?/sec
gt_scalar_mul                   1.00    601.5±6.61µs        ? ?/sec    1.48    892.2±3.48µs        ? ?/sec
multi_pairing/16                1.00      4.9±0.01ms        ? ?/sec    1.17      5.8±0.03ms        ? ?/sec
multi_pairing/2                 1.00   828.3±10.81µs        ? ?/sec    1.50  1243.6±15.90µs        ? ?/sec
multi_pairing/4                 1.00   1524.5±8.08µs        ? ?/sec    1.20  1832.3±23.58µs        ? ?/sec
multi_pairing/8                 1.00      2.7±0.01ms        ? ?/sec    1.17      3.2±0.08ms        ? ?/sec
pairing                         1.00    622.9±5.46µs        ? ?/sec    1.48   923.7±17.24µs        ? ?/sec
pedersen_commit/1024            1.00     10.9±0.04ms        ? ?/sec    1.17     12.8±0.04ms        ? ?/sec
pedersen_commit/16              1.00    524.5±3.83µs        ? ?/sec    1.15    602.0±6.82µs        ? ?/sec
pedersen_commit/256             1.00      3.7±0.00ms        ? ?/sec    1.17      4.4±0.03ms        ? ?/sec
pedersen_commit/4               1.00    277.8±1.21µs        ? ?/sec    1.14    317.9±2.97µs        ? ?/sec
pedersen_commit/64              1.00  1342.1±25.76µs        ? ?/sec    1.24  1660.3±19.72µs        ? ?/sec

Conflict resolutions:
- Cargo.toml: keep the a16z/dory#26 git pin (parallel prepared-point cache
  init); dory-pcs 0.4.1 on main does not contain that change (dory#26 is
  closed, 0.4.1 ships dory#27's routine ops only).
- Cargo.lock: main's lock + minimal re-resolve for the dory git source.
- tracer/src/execution_backend.rs: both sides are additive — keep the
  parallel Cycle->TraceRow conversion (this PR) alongside the chunked
  execution seam and its tests (#1728). mod tests keeps the unconditional
  expect(clippy::unwrap_used) for parallel_cycle_conversion_matches_serial.
@github-actions

github-actions Bot commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor
@@              added  removed @@
+ actual code     +77
- actual code              -24
  tests             0        0
  docs              0        0
+ fixtures         +2
  helper scripts    0        0
  ----------------------------
+ total           +79
- total                    -24

@0xAndoroid
0xAndoroid requested a review from a16z-bsaari August 19, 2026 21:17
@0xAndoroid
0xAndoroid marked this pull request as ready for review August 19, 2026 21:17

@a16z-bsaari a16z-bsaari left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test

@0xAndoroid
0xAndoroid marked this pull request as draft August 19, 2026 21:19
@0xAndoroid
0xAndoroid marked this pull request as ready for review August 20, 2026 17:12
@0xAndoroid
0xAndoroid merged commit db62bde into main Aug 21, 2026
46 checks passed
@0xAndoroid
0xAndoroid deleted the perf/preprocessing-parallel branch August 21, 2026 01:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-spec PR has no spec file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants