diff --git a/halo2_proofs/src/poly.rs b/halo2_proofs/src/poly.rs index 753b65eb8..73031406f 100644 --- a/halo2_proofs/src/poly.rs +++ b/halo2_proofs/src/poly.rs @@ -169,22 +169,39 @@ impl Polynomial { let poly_len = u32::from_be_bytes(poly_len) as usize; let repr_len = F::default().to_repr().as_ref().len(); + let total_len = poly_len * repr_len; - let mut new_vals = vec![0u8; poly_len * repr_len]; + let mut new_vals = vec![0u8; total_len]; reader.read_exact(&mut new_vals)?; + let default_parallelism_approx = match std::thread::available_parallelism() { + Ok(parallelism) => usize::from(parallelism), + _ => 1, + }; + + log::debug!( + "[parallel-poly-read] default_parallelism_approx = {}", + default_parallelism_approx + ); + + let num_of_reps_per_chunk = std::cmp::max(1, poly_len / default_parallelism_approx); + let chunk_size = num_of_reps_per_chunk * repr_len; + // parallel read - new_vals - .par_chunks_mut(repr_len) - .map(|chunk| { - let mut chunk = io::Cursor::new(chunk); - F::read(&mut chunk, format) - }) - .collect::>>() - .map(|values| Self { - values, - _marker: PhantomData, - }) + Ok(Self { + values: new_vals + .par_chunks(chunk_size) + .map(|mut chunk| { + let mut felts = Vec::with_capacity(num_of_reps_per_chunk); + while !chunk.is_empty() { + felts.push(F::read(&mut chunk, format).unwrap()); + } + felts + }) + .flatten() + .collect::>(), + _marker: PhantomData, + }) } /// Reads polynomial from buffer using `SerdePrimeField::read`.