Skip to content

Commit c9afbc7

Browse files
authored
Custom thread pool (#239)
removes rayon + increases perf
1 parent e12109b commit c9afbc7

56 files changed

Lines changed: 1720 additions & 1541 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 65 additions & 99 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ members = [
1919
"crates/backend/fiat-shamir",
2020
"crates/backend/sumcheck",
2121
"crates/backend/system-info",
22+
"crates/backend/parallel",
2223
"crates/backend/zk-alloc",
2324
]
2425

@@ -60,14 +61,14 @@ lean_compiler = { path = "crates/lean_compiler" }
6061
lean_prover = { path = "crates/lean_prover" }
6162
rec_aggregation = { path = "crates/rec_aggregation" }
6263
backend = { path = "crates/backend" }
63-
zk-alloc = { path = "crates/backend/zk-alloc" }
6464
system-info = { path = "crates/backend/system-info" }
65+
parallel = { path = "crates/backend/parallel" }
66+
zk-alloc = { path = "crates/backend/zk-alloc" }
6567

6668
# External
6769
sha3 = "0.11.0"
6870
clap = { version = "4.5.59", features = ["derive"] }
6971
rand = "0.10.0"
70-
rayon = "1.11.0"
7172
pest = "2.7"
7273
pest_derive = "2.7"
7374
itertools = "0.14.0"
@@ -82,12 +83,14 @@ include_dir = "0.7"
8283

8384
[features]
8485
prox-gaps-conjecture = ["rec_aggregation/prox-gaps-conjecture"]
86+
# Build with the plain system allocator instead of zk-alloc (for comparison/debugging).
8587
standard-alloc = ["rec_aggregation/standard-alloc"]
8688

8789
[dependencies]
8890
clap.workspace = true
8991
rec_aggregation.workspace = true
9092
zk-alloc.workspace = true
93+
libc = "0.2"
9194
rand.workspace = true
9295
sub_protocols.workspace = true
9396
lean_vm.workspace = true

README.md

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ cargo run --release -- xmss --n-signatures 1550 --log-inv-rate 1
3636

3737
| WHIR rate | Proven Regime | Proximity Gaps Conjecture |
3838
| --------- | --------------------- | ------------------------- |
39-
| 1/2 | 1319 XMSS/s - 338 KiB | 1345 XMSS/s - 176 KiB |
40-
| 1/4 | 961 XMSS/s - 228 KiB | 969 XMSS/s - 126 KiB |
39+
| 1/2 | 1453 XMSS/s - 344 KiB | 1500 XMSS/s - 178 KiB |
40+
| 1/4 | 1058 XMSS/s - 229 KiB | 1065 XMSS/s - 127 KiB |
4141

4242

4343
(Proving throughput - proof size)
@@ -54,15 +54,14 @@ cargo run --release -- recursion --n 2 --log-inv-rate 2
5454

5555
| n | WHIR rate | Proven Regime | Proximity Gaps Conjecture |
5656
| --- | --------- | --------------------------- | --------------------------- |
57-
| 1 | 1/2 | 0.39s = 1 x 0.39s - 278 KiB | 0.24s = 1 x 0.24s - 147 KiB |
58-
| 1 | 1/4 | 0.32s = 1 x 0.32s - 188 KiB | 0.27s = 1 x 0.27s - 100 KiB |
59-
| 2 | 1/2 | 0.7s = 2 x 0.35s - 293 KiB | 0.43s = 2 x 0.21s - 157 KiB |
60-
| 2 | 1/4 | 0.56s = 2 x 0.28s - 194 KiB | 0.43s = 2 x 0.22s - 102 KiB |
61-
| 3 | 1/2 | 0.85s = 3 x 0.28s - 312 KiB | 0.63s = 3 x 0.21s - 150 KiB |
62-
| 3 | 1/4 | 0.94s = 3 x 0.31s - 203 KiB | 0.73s = 3 x 0.24s - 108 KiB |
63-
| 4 | 1/2 | 1.27s = 4 x 0.32s - 308 KiB | 0.78s = 4 x 0.2s - 166 KiB |
64-
| 4 | 1/4 | 1.02s = 4 x 0.26s - 206 KiB | 0.79s = 4 x 0.2s - 108 KiB |
65-
57+
| 1 | 1/2 | 0.22s = 1 x 0.22s - 285 KiB | 0.15s = 1 x 0.15s - 143 KiB |
58+
| 1 | 1/4 | 0.24s = 1 x 0.24s - 189 KiB | 0.18s = 1 x 0.18s - 98 KiB |
59+
| 2 | 1/2 | 0.52s = 2 x 0.26s - 282 KiB | 0.33s = 2 x 0.16s - 159 KiB |
60+
| 2 | 1/4 | 0.45s = 2 x 0.23s - 198 KiB | 0.33s = 2 x 0.16s - 102 KiB |
61+
| 3 | 1/2 | 0.7s = 3 x 0.23s - 317 KiB | 0.47s = 3 x 0.16s - 151 KiB |
62+
| 3 | 1/4 | 0.67s = 3 x 0.22s - 191 KiB | 0.43s = 3 x 0.14s - 111 KiB |
63+
| 4 | 1/2 | 1.02s = 4 x 0.26s - 309 KiB | 0.61s = 4 x 0.15s - 168 KiB |
64+
| 4 | 1/4 | 0.85s = 4 x 0.21s - 208 KiB | 0.62s = 4 x 0.15s - 109 KiB |
6665

6766

6867
(time for n->1 recursive aggregation - proof size)

crates/backend/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ poly = { path = "poly", package = "mt-poly" }
99
sumcheck = { path = "sumcheck", package = "mt-sumcheck" }
1010
field = { path = "field", package = "mt-field" }
1111
air = { path = "air", package = "mt-air" }
12-
rayon.workspace = true
12+
parallel.workspace = true
1313
whir = { path = "../whir", package = "mt-whir" }
1414
tracing.workspace = true
1515
fiat-shamir = { path = "fiat-shamir", package = "mt-fiat-shamir" }

crates/backend/fiat-shamir/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ symetric = { path = "../symetric", package = "mt-symetric" }
1010
utils = { path = "../utils", package = "utils" }
1111
tracing.workspace = true
1212
serde.workspace = true
13-
rayon.workspace = true
13+
parallel.workspace = true

crates/backend/fiat-shamir/src/prover.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use field::PrimeCharacteristicRing;
66
use field::integers::QuotientMap;
77
use field::{ExtensionField, PrimeField64};
88
use koala_bear::symmetric::Permutation;
9-
use rayon::prelude::*;
10-
use std::sync::atomic::{AtomicU64, Ordering};
9+
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
1110
use std::time::Duration;
1211
use std::{fmt::Debug, sync::Mutex, time::Instant};
1312
use symetric::CAPACITY;
@@ -132,9 +131,18 @@ where
132131
let witness_found = Mutex::<Option<PF<EF>>>::new(None);
133132
// each batch tests lanes witnesses simultaneously
134133
let num_batches = PF::<EF>::ORDER_U64.div_ceil(lanes as u64);
135-
(0..num_batches)
136-
.into_par_iter()
137-
.find_any(|&batch| {
134+
135+
let next_batch = AtomicU64::new(0);
136+
let found = AtomicBool::new(false);
137+
parallel::for_each_index(parallel::num_threads(), |_| {
138+
loop {
139+
if found.load(Ordering::Relaxed) {
140+
return;
141+
}
142+
let batch = next_batch.fetch_add(1, Ordering::Relaxed);
143+
if batch >= num_batches {
144+
return;
145+
}
138146
let base = batch * lanes as u64;
139147

140148
let packed_witnesses = Packed::<EF>::from_fn(|lane| {
@@ -159,12 +167,13 @@ where
159167
let rand_usize = sample.as_canonical_u64() as usize;
160168
if (rand_usize & ((1 << bits) - 1)) == 0 {
161169
*witness_found.lock().unwrap() = Some(*witness);
162-
return true;
170+
found.store(true, Ordering::Relaxed);
171+
return;
163172
}
164173
}
165-
false
166-
})
167-
.expect("failed to find witness");
174+
}
175+
});
176+
assert!(found.load(Ordering::Relaxed), "failed to find witness");
168177

169178
let witness = witness_found.lock().unwrap().unwrap();
170179

crates/backend/field/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ utils = { path = "../utils", package = "utils" }
99
itertools.workspace = true
1010
num-bigint = "*"
1111
paste = "*"
12+
parallel.workspace = true
1213
rand.workspace = true
13-
rayon.workspace = true
1414
serde.workspace = true
1515
tracing.workspace = true

crates/backend/field/src/field.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAss
99
use core::{array, slice};
1010

1111
use num_bigint::BigUint;
12-
use rayon::{current_num_threads, prelude::*};
1312
use serde::Serialize;
1413
use serde::de::DeserializeOwned;
1514
use utils::{flatten_to_base, iter_array_chunks_padded};
@@ -1020,24 +1019,21 @@ impl<F: Field> BoundedPowers<F> {
10201019
let mut points_packed = F::Packing::zero_vec(num_packed);
10211020

10221021
// Split computation evenly among threads
1023-
let num_threads = current_num_threads().max(1);
1022+
let num_threads = parallel::num_threads().max(1);
10241023
let chunk_size = num_packed.div_ceil(num_threads);
10251024

10261025
// Precompute base for each chunk.
10271026
let base = self.iter.base;
10281027
let chunk_base = base.exp_u64((chunk_size * width) as u64);
10291028
let shift = self.iter.current;
10301029

1031-
points_packed
1032-
.par_chunks_mut(chunk_size)
1033-
.enumerate()
1034-
.for_each(|(chunk_idx, chunk_slice)| {
1035-
// First power in this chunk
1036-
let chunk_start = shift * chunk_base.exp_u64(chunk_idx as u64);
1030+
parallel::par_chunks_mut(&mut points_packed, chunk_size, |chunk_idx, chunk_slice| {
1031+
// First power in this chunk
1032+
let chunk_start = shift * chunk_base.exp_u64(chunk_idx as u64);
10371033

1038-
// Fill the chunk with packed powers.
1039-
F::Packing::packed_shifted_powers(base, chunk_start).fill(chunk_slice);
1040-
});
1034+
// Fill the chunk with packed powers.
1035+
F::Packing::packed_shifted_powers(base, chunk_start).fill(chunk_slice);
1036+
});
10411037

10421038
// return the number of requested points, discarding the unused packed powers
10431039
// SAFETY: size_of::<F::Packing> always divides size_of::<F::Packing>.

crates/backend/koala-bear/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ field = { path = "../field", package = "mt-field" }
88
utils = { path = "../utils", package = "utils" }
99

1010
rand.workspace = true
11-
rayon.workspace = true
1211
serde.workspace = true
1312
itertools.workspace = true
1413
tracing.workspace = true

crates/backend/parallel/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "parallel"
3+
version.workspace = true
4+
edition.workspace = true
5+
description = "Minimal fixed-size thread pool for static data-parallel kernels"
6+
7+
[dependencies]
8+
system-info.workspace = true
9+
10+
[lints]
11+
workspace = true

0 commit comments

Comments
 (0)