Skip to content

Commit 1e217ad

Browse files
diegokingstongabrielbosio
authored andcommitted
perf(stark): deduplicate LdeTwiddles by domain size in multi_prove
Tables sharing the same lde_size now reuse a single Arc<LdeTwiddles> instead of each allocating their own copy. This avoids redundant twiddle computation and allocation when multiple tables happen to have the same trace length (e.g., all 2^19-row tables after the cap change).
1 parent 0571e45 commit 1e217ad

1 file changed

Lines changed: 32 additions & 8 deletions

File tree

crypto/stark/src/prover.rs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ pub trait IsStarkProver<
635635
air_trace_pairs: &[AirTracePair<'_, Field, FieldExtension, PI>],
636636
metadatas: &[Round1Metadata<Field, FieldExtension>],
637637
domains: &[Domain<Field>],
638-
twiddle_caches: &[LdeTwiddles<Field>],
638+
twiddle_caches: &[Arc<LdeTwiddles<Field>>],
639639
main_pool: &mut [Vec<FieldElement<Field>>],
640640
aux_pool: &mut [Vec<FieldElement<FieldExtension>>],
641641
) where
@@ -651,7 +651,13 @@ pub trait IsStarkProver<
651651
.zip(domains.iter().zip(twiddle_caches.iter()))
652652
{
653653
let result = Self::reconstruct_round1(
654-
*air, *trace, domain, metadata, twiddles, main_pool, aux_pool,
654+
*air,
655+
*trace,
656+
domain,
657+
metadata,
658+
&**twiddles,
659+
main_pool,
660+
aux_pool,
655661
)
656662
.expect("reconstruct_round1 failed in debug-checks");
657663
temp_results.push(result);
@@ -1512,24 +1518,42 @@ pub trait IsStarkProver<
15121518
let phase_start = Instant::now();
15131519

15141520
let mut domains = Vec::with_capacity(num_airs);
1515-
let mut twiddle_caches: Vec<LdeTwiddles<Field>> = Vec::with_capacity(num_airs);
1521+
let mut twiddle_caches: Vec<Arc<LdeTwiddles<Field>>> = Vec::with_capacity(num_airs);
15161522
let mut max_main_cols = 0usize;
15171523
let mut max_aux_cols = 0usize;
15181524
let mut max_lde_size = 0usize;
15191525

1526+
// Deduplicate twiddle caches: tables with identical domain parameters share one Arc.
1527+
// Key on (interpolation_domain_size, blowup_factor, coset_offset_bytes) because each
1528+
// affects the twiddle values: interpolation_domain_size sizes `inv` and `coset_weights`,
1529+
// blowup_factor sizes `fwd`, and coset_offset sets `coset_weights` values.
1530+
// coset_offset is serialized via AsBytes since FieldElement<F> does not impl Hash without
1531+
// a BaseType: Hash bound.
1532+
let mut twiddle_by_domain: std::collections::HashMap<
1533+
(usize, usize, Vec<u8>),
1534+
Arc<LdeTwiddles<Field>>,
1535+
> = std::collections::HashMap::new();
1536+
15201537
for (air, trace, _pub_inputs) in &*air_trace_pairs {
15211538
let trace_length = trace.num_rows();
15221539
let domain = new_domain(*air, trace_length);
15231540

15241541
let lde_size = domain.interpolation_domain_size * domain.blowup_factor;
1525-
let twiddles = LdeTwiddles::new(&domain);
1542+
let key = (
1543+
domain.interpolation_domain_size,
1544+
domain.blowup_factor,
1545+
domain.coset_offset.as_bytes(),
1546+
);
1547+
let twiddles = twiddle_by_domain
1548+
.entry(key)
1549+
.or_insert_with(|| Arc::new(LdeTwiddles::new(&domain)));
15261550

15271551
max_main_cols = max_main_cols.max(trace.num_main_columns);
15281552
max_aux_cols = max_aux_cols.max(air.num_auxiliary_rap_columns());
15291553
max_lde_size = max_lde_size.max(lde_size);
15301554

15311555
domains.push(domain);
1532-
twiddle_caches.push(twiddles);
1556+
twiddle_caches.push(Arc::clone(twiddles));
15331557
}
15341558

15351559
// Allocate K independent LDE column buffer pool sets for parallel table processing.
@@ -1573,7 +1597,7 @@ pub trait IsStarkProver<
15731597
let idx = chunk_start + j;
15741598
let (air, trace, _) = &air_trace_pairs[idx];
15751599
let domain = &domains[idx];
1576-
let twiddles = &twiddle_caches[idx];
1600+
let twiddles = &*twiddle_caches[idx];
15771601

15781602
if air.is_preprocessed() {
15791603
Self::commit_preprocessed_trace(
@@ -1693,7 +1717,7 @@ pub trait IsStarkProver<
16931717
let idx = chunk_start + j;
16941718
let (air, trace, _) = &air_trace_pairs[idx];
16951719
let domain = &domains[idx];
1696-
let twiddles = &twiddle_caches[idx];
1720+
let twiddles = &*twiddle_caches[idx];
16971721

16981722
if air.has_aux_trace() {
16991723
let num_aux_cols = trace.num_aux_columns;
@@ -1809,7 +1833,7 @@ pub trait IsStarkProver<
18091833
let (air, trace, pub_inputs) = &air_trace_pairs[idx];
18101834
let metadata = &metadatas[idx];
18111835
let domain = &domains[idx];
1812-
let twiddles = &twiddle_caches[idx];
1836+
let twiddles = &*twiddle_caches[idx];
18131837

18141838
#[cfg(feature = "instruments")]
18151839
let table_start = Instant::now();

0 commit comments

Comments
 (0)