Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

Commit 703a164

Browse files
authored
parallelize mpt table loading (#1067)
1 parent 57a2dd4 commit 703a164

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

zkevm-circuits/src/mpt_circuit.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,24 @@ impl SubCircuit<Fr> for MptCircuit<Fr> {
138138
layouter: &mut impl Layouter<Fr>,
139139
) -> Result<(), Error> {
140140
config.0.assign(layouter, &self.proofs, self.row_limit)?;
141-
config.1.load(
142-
layouter,
143-
&self.mpt_updates,
144-
self.row_limit,
145-
challenges.evm_word(),
146-
)?;
141+
// use par assignment of mpt table by default.
142+
// to use serial version, you must set `PARALLEL_SYN=false`.
143+
let use_seq = std::env::var("PARALLEL_SYN").map_or(false, |s| s == *"false");
144+
if !use_seq {
145+
config.1.load_par(
146+
layouter,
147+
&self.mpt_updates,
148+
self.row_limit,
149+
challenges.evm_word(),
150+
)?;
151+
} else {
152+
config.1.load(
153+
layouter,
154+
&self.mpt_updates,
155+
self.row_limit,
156+
challenges.evm_word(),
157+
)?;
158+
}
147159
Ok(())
148160
}
149161

zkevm-circuits/src/table.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,46 @@ impl MptTable {
811811
)
812812
}
813813

814+
pub(crate) fn load_par<F: Field>(
815+
&self,
816+
layouter: &mut impl Layouter<F>,
817+
updates: &MptUpdates,
818+
max_mpt_rows: usize,
819+
randomness: Value<F>,
820+
) -> Result<(), Error> {
821+
let num_threads = std::thread::available_parallelism().unwrap().get();
822+
let chunk_size = (max_mpt_rows + num_threads - 1) / num_threads;
823+
let mpt_update_rows = updates
824+
.table_assignments(randomness)
825+
.into_iter()
826+
.chain(repeat(MptUpdateRow::padding()))
827+
.take(max_mpt_rows)
828+
.collect_vec();
829+
let mut is_first_passes = vec![true; num_threads];
830+
let assignments = mpt_update_rows
831+
.chunks(chunk_size)
832+
.zip(is_first_passes.iter_mut())
833+
.map(|(mpt_update_rows, is_first_pass)| {
834+
|mut region: Region<'_, F>| -> Result<(), Error> {
835+
if *is_first_pass {
836+
*is_first_pass = false;
837+
let last_off = mpt_update_rows.len() - 1;
838+
self.assign(&mut region, last_off, &mpt_update_rows[last_off])?;
839+
return Ok(());
840+
}
841+
for (offset, row) in mpt_update_rows.iter().enumerate() {
842+
self.assign(&mut region, offset, row)?;
843+
}
844+
Ok(())
845+
}
846+
})
847+
.collect_vec();
848+
849+
layouter.assign_regions(|| "mpt table zkevm", assignments)?;
850+
851+
Ok(())
852+
}
853+
814854
pub(crate) fn load_with_region<F: Field>(
815855
&self,
816856
region: &mut Region<'_, F>,

0 commit comments

Comments
 (0)