diff --git a/Cargo.lock b/Cargo.lock index 01c0aac10d..cf9b127d08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1320,11 +1320,11 @@ dependencies = [ [[package]] name = "blst" version = "0.3.11" -source = "git+https://github.com/supranational/blst.git#0d46eefa45fc1e57aceb42bba0e84eab3a7a9725" +source = "git+https://github.com/subspace/blst?rev=ab042e18cb3b62e131423380513964e4b2c7b445#ab042e18cb3b62e131423380513964e4b2c7b445" dependencies = [ "cc", "glob", - "threadpool", + "rayon", "zeroize", ] diff --git a/Cargo.toml b/Cargo.toml index 37eed29b02..39a43f7fd9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -138,3 +138,8 @@ sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/polka sp-io = { version = "23.0.0", git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" } sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" } substrate-prometheus-endpoint = { version = "0.10.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" } + +# TODO: Importing https://github.com/supranational/blst/pull/203 to take advantage of optimizations introduced there, +# switch to upstream once merged or once similar performance improvements land upstream +[patch."https://github.com/supranational/blst.git"] +blst = { git = "https://github.com/subspace/blst", rev = "ab042e18cb3b62e131423380513964e4b2c7b445" } diff --git a/crates/pallet-subspace/src/mock.rs b/crates/pallet-subspace/src/mock.rs index b7322ecb57..61c48d2bc4 100644 --- a/crates/pallet-subspace/src/mock.rs +++ b/crates/pallet-subspace/src/mock.rs @@ -38,11 +38,11 @@ use sp_runtime::testing::{Digest, DigestItem, Header, TestXt}; use sp_runtime::traits::{Block as BlockT, Header as _, IdentityLookup}; use sp_runtime::{BuildStorage, Perbill}; use sp_weights::Weight; -use std::iter; use std::marker::PhantomData; use std::num::{NonZeroU32, NonZeroU64, NonZeroUsize}; use std::simd::Simd; use std::sync::{Once, OnceLock}; +use std::{iter, slice}; use subspace_archiving::archiver::{Archiver, NewArchivedSegment}; use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg}; use subspace_core_primitives::crypto::Scalar; @@ -464,7 +464,7 @@ pub fn create_signed_vote( sector_metadata_output: &mut plotted_sector_metadata_bytes, downloading_semaphore: None, encoding_semaphore: None, - table_generator: &mut table_generator, + table_generators: slice::from_mut(&mut table_generator), abort_early: &Default::default(), })) .unwrap(); diff --git a/crates/subspace-farmer-components/benches/auditing.rs b/crates/subspace-farmer-components/benches/auditing.rs index df03412437..d21422436f 100644 --- a/crates/subspace-farmer-components/benches/auditing.rs +++ b/crates/subspace-farmer-components/benches/auditing.rs @@ -128,7 +128,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { sector_metadata_output: &mut plotted_sector_metadata_bytes, downloading_semaphore: black_box(None), encoding_semaphore: black_box(None), - table_generator: &mut table_generator, + table_generators: slice::from_mut(&mut table_generator), abort_early: &Default::default(), })) .unwrap(); diff --git a/crates/subspace-farmer-components/benches/plotting.rs b/crates/subspace-farmer-components/benches/plotting.rs index e4c97b03ef..eb77765438 100644 --- a/crates/subspace-farmer-components/benches/plotting.rs +++ b/crates/subspace-farmer-components/benches/plotting.rs @@ -35,7 +35,16 @@ fn criterion_benchmark(c: &mut Criterion) { .expect("Not zero; qed"), ) .unwrap(); - let mut table_generator = PosTable::generator(); + let mut table_generators = [ + PosTable::generator(), + PosTable::generator(), + PosTable::generator(), + PosTable::generator(), + PosTable::generator(), + PosTable::generator(), + PosTable::generator(), + PosTable::generator(), + ]; let archived_history_segment = archiver .add_block( AsRef::<[u8]>::as_ref(input.as_ref()).to_vec(), @@ -79,7 +88,7 @@ fn criterion_benchmark(c: &mut Criterion) { sector_metadata_output: black_box(&mut sector_metadata_bytes), downloading_semaphore: black_box(None), encoding_semaphore: black_box(None), - table_generator: black_box(&mut table_generator), + table_generators: black_box(&mut table_generators), abort_early: &Default::default(), })) .unwrap(); diff --git a/crates/subspace-farmer-components/benches/proving.rs b/crates/subspace-farmer-components/benches/proving.rs index 7ffe1536ca..b9e40b1dc5 100644 --- a/crates/subspace-farmer-components/benches/proving.rs +++ b/crates/subspace-farmer-components/benches/proving.rs @@ -135,7 +135,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { sector_metadata_output: &mut plotted_sector_metadata_bytes, downloading_semaphore: black_box(None), encoding_semaphore: black_box(None), - table_generator: &mut table_generator, + table_generators: slice::from_mut(&mut table_generator), abort_early: &Default::default(), })) .unwrap(); diff --git a/crates/subspace-farmer-components/benches/reading.rs b/crates/subspace-farmer-components/benches/reading.rs index 38a6754cd9..5d7ab92202 100644 --- a/crates/subspace-farmer-components/benches/reading.rs +++ b/crates/subspace-farmer-components/benches/reading.rs @@ -6,7 +6,7 @@ use rand::prelude::*; use std::fs::OpenOptions; use std::io::Write; use std::num::{NonZeroU64, NonZeroUsize}; -use std::{env, fs}; +use std::{env, fs, slice}; use subspace_archiving::archiver::Archiver; use subspace_core_primitives::crypto::kzg; use subspace_core_primitives::crypto::kzg::Kzg; @@ -128,7 +128,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { sector_metadata_output: &mut plotted_sector_metadata_bytes, downloading_semaphore: black_box(None), encoding_semaphore: black_box(None), - table_generator: &mut table_generator, + table_generators: slice::from_mut(&mut table_generator), abort_early: &Default::default(), })) .unwrap(); diff --git a/crates/subspace-farmer-components/src/plotting.rs b/crates/subspace-farmer-components/src/plotting.rs index 9f1d4648c8..58f43e6f27 100644 --- a/crates/subspace-farmer-components/src/plotting.rs +++ b/crates/subspace-farmer-components/src/plotting.rs @@ -12,11 +12,11 @@ use futures::StreamExt; use parity_scale_codec::{Decode, Encode}; use parking_lot::Mutex; use rayon::prelude::*; +use std::mem; use std::simd::Simd; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; -use std::{mem, slice}; use subspace_core_primitives::crypto::kzg::Kzg; use subspace_core_primitives::crypto::{blake3_hash, blake3_hash_parallel, Scalar}; use subspace_core_primitives::{ @@ -147,8 +147,8 @@ where /// Semaphore for part of the plotting when farmer encodes downloaded sector, should typically /// allow one permit at a time for efficient CPU utilization pub encoding_semaphore: Option<&'a Semaphore>, - /// Proof of space table generator - pub table_generator: &'a mut PosTable::Generator, + /// Proof of space table generators + pub table_generators: &'a mut [PosTable::Generator], /// Whether encoding should be aborted early pub abort_early: &'a AtomicBool, } @@ -179,7 +179,7 @@ where sector_metadata_output, downloading_semaphore, encoding_semaphore, - table_generator, + table_generators, abort_early, } = options; @@ -211,7 +211,7 @@ where pieces_in_sector, sector_output, sector_metadata_output, - table_generators: slice::from_mut(table_generator), + table_generators, abort_early, }, ) @@ -349,7 +349,7 @@ where /// Where plotted sector metadata should be written, vector must either be empty (in which case /// it'll be resized to correct size automatically) or correctly sized from the beginning pub sector_metadata_output: &'a mut Vec, - /// Proof of space table generator + /// Proof of space table generators pub table_generators: &'a mut [PosTable::Generator], /// Whether encoding should be aborted early pub abort_early: &'a AtomicBool, @@ -419,7 +419,7 @@ where loop { // This instead of `while` above because otherwise mutex will be held for - // the duration of the loop and wil limit concurrency to 1 table generator + // the duration of the loop and will limit concurrency to 1 table generator let Some(((piece_offset, record), encoded_chunks_used)) = iter.lock().next() else { @@ -561,6 +561,7 @@ fn record_encoding( .extend(&source_record_chunks) .expect("Instance was verified to be able to work with this many values earlier; qed"); + chunks_scratch.clear(); // For every erasure coded chunk check if there is quality present, if so then encode // with PoSpace quality bytes and set corresponding `quality_present` bit to `true` (u16::from(SBucket::ZERO)..=u16::from(SBucket::MAX)) diff --git a/crates/subspace-proof-of-space/src/chiapos/table.rs b/crates/subspace-proof-of-space/src/chiapos/table.rs index c26399de65..2881171aae 100644 --- a/crates/subspace-proof-of-space/src/chiapos/table.rs +++ b/crates/subspace-proof-of-space/src/chiapos/table.rs @@ -791,7 +791,7 @@ where let mut positions = Vec::with_capacity(t_n.len()); let mut metadatas = Vec::with_capacity(t_n.len()); - for (y, [left_position, right_position], metadata) in t_n { + for (y, [left_position, right_position], metadata) in t_n.drain(..) { ys.push(y); positions.push([left_position, right_position]); // Last table doesn't have metadata @@ -800,6 +800,11 @@ where } } + // Drop from a background thread, which typically helps with overall concurrency + rayon::spawn(move || { + drop(t_n); + }); + Self::Other { ys, positions, diff --git a/test/subspace-test-client/src/lib.rs b/test/subspace-test-client/src/lib.rs index b2e8345e56..c9ed40e8b9 100644 --- a/test/subspace-test-client/src/lib.rs +++ b/test/subspace-test-client/src/lib.rs @@ -31,6 +31,7 @@ use sp_api::ProvideRuntimeApi; use sp_consensus_subspace::{FarmerPublicKey, FarmerSignature, SubspaceApi}; use sp_core::{Decode, Encode}; use std::num::{NonZeroU64, NonZeroUsize}; +use std::slice; use std::sync::Arc; use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg}; use subspace_core_primitives::objects::BlockObjectMapping; @@ -245,7 +246,7 @@ where sector_metadata_output: &mut sector_metadata, downloading_semaphore: None, encoding_semaphore: None, - table_generator: &mut table_generator, + table_generators: slice::from_mut(&mut table_generator), abort_early: &Default::default(), }) .await