initializes thread-pools with lazy_static instead of thread_local (#24853)
In addition to thread_local -> lazy_static change, a number of thread-pools are initialized with get_max_thread_count to achieve parity with the older code in terms of number of validator threads.
This commit is contained in:
parent
7100f1c94b
commit
a01291069a
|
@ -4618,6 +4618,7 @@ dependencies = [
|
||||||
"fs_extra",
|
"fs_extra",
|
||||||
"histogram",
|
"histogram",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"lru",
|
"lru",
|
||||||
"matches",
|
"matches",
|
||||||
|
@ -4721,6 +4722,7 @@ dependencies = [
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"dlopen",
|
"dlopen",
|
||||||
"dlopen_derive",
|
"dlopen_derive",
|
||||||
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"matches",
|
"matches",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
|
|
|
@ -25,6 +25,7 @@ etcd-client = { version = "0.9.1", features = ["tls"] }
|
||||||
fs_extra = "1.2.0"
|
fs_extra = "1.2.0"
|
||||||
histogram = "0.6.9"
|
histogram = "0.6.9"
|
||||||
itertools = "0.10.3"
|
itertools = "0.10.3"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
lru = "0.7.5"
|
lru = "0.7.5"
|
||||||
min-max-heap = "1.3.0"
|
min-max-heap = "1.3.0"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crossbeam_channel::{Receiver, RecvTimeoutError, Sender},
|
crossbeam_channel::{Receiver, RecvTimeoutError, Sender},
|
||||||
|
lazy_static::lazy_static,
|
||||||
rayon::{prelude::*, ThreadPool},
|
rayon::{prelude::*, ThreadPool},
|
||||||
solana_gossip::cluster_info::ClusterInfo,
|
solana_gossip::cluster_info::ClusterInfo,
|
||||||
solana_measure::measure::Measure,
|
solana_measure::measure::Measure,
|
||||||
|
@ -9,7 +10,6 @@ use {
|
||||||
solana_sdk::timing::timestamp,
|
solana_sdk::timing::timestamp,
|
||||||
solana_streamer::streamer::{self, StreamerError},
|
solana_streamer::streamer::{self, StreamerError},
|
||||||
std::{
|
std::{
|
||||||
cell::RefCell,
|
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
net::IpAddr,
|
net::IpAddr,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
|
@ -20,11 +20,13 @@ use {
|
||||||
|
|
||||||
const IP_TO_STAKE_REFRESH_DURATION: Duration = Duration::from_secs(5);
|
const IP_TO_STAKE_REFRESH_DURATION: Duration = Duration::from_secs(5);
|
||||||
|
|
||||||
thread_local!(static PAR_THREAD_POOL: RefCell<ThreadPool> = RefCell::new(rayon::ThreadPoolBuilder::new()
|
lazy_static! {
|
||||||
|
static ref PAR_THREAD_POOL: ThreadPool = rayon::ThreadPoolBuilder::new()
|
||||||
.num_threads(get_thread_count())
|
.num_threads(get_thread_count())
|
||||||
.thread_name(|ix| format!("transaction_sender_stake_stage_{}", ix))
|
.thread_name(|ix| format!("transaction_sender_stake_stage_{}", ix))
|
||||||
.build()
|
.build()
|
||||||
.unwrap()));
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
pub type FindPacketSenderStakeSender = Sender<Vec<PacketBatch>>;
|
pub type FindPacketSenderStakeSender = Sender<Vec<PacketBatch>>;
|
||||||
pub type FindPacketSenderStakeReceiver = Receiver<Vec<PacketBatch>>;
|
pub type FindPacketSenderStakeReceiver = Receiver<Vec<PacketBatch>>;
|
||||||
|
@ -166,8 +168,7 @@ impl FindPacketSenderStakeStage {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_sender_stakes(batches: &mut [PacketBatch], ip_to_stake: &HashMap<IpAddr, u64>) {
|
fn apply_sender_stakes(batches: &mut [PacketBatch], ip_to_stake: &HashMap<IpAddr, u64>) {
|
||||||
PAR_THREAD_POOL.with(|thread_pool| {
|
PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
batches
|
batches
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.flat_map(|batch| batch.packets.par_iter_mut())
|
.flat_map(|batch| batch.packets.par_iter_mut())
|
||||||
|
@ -175,7 +176,6 @@ impl FindPacketSenderStakeStage {
|
||||||
packet.meta.sender_stake =
|
packet.meta.sender_stake =
|
||||||
*ip_to_stake.get(&packet.meta.addr().ip()).unwrap_or(&0);
|
*ip_to_stake.get(&packet.meta.addr().ip()).unwrap_or(&0);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ bincode = "1.3.3"
|
||||||
crossbeam-channel = "0.5"
|
crossbeam-channel = "0.5"
|
||||||
dlopen = "0.1.8"
|
dlopen = "0.1.8"
|
||||||
dlopen_derive = "0.1.4"
|
dlopen_derive = "0.1.4"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
rand = "0.7.0"
|
rand = "0.7.0"
|
||||||
rayon = "1.5.2"
|
rayon = "1.5.2"
|
||||||
|
|
|
@ -7,6 +7,7 @@ use {
|
||||||
crossbeam_channel::{Receiver, Sender},
|
crossbeam_channel::{Receiver, Sender},
|
||||||
dlopen::symbor::{Container, SymBorApi, Symbol},
|
dlopen::symbor::{Container, SymBorApi, Symbol},
|
||||||
dlopen_derive::SymBorApi,
|
dlopen_derive::SymBorApi,
|
||||||
|
lazy_static::lazy_static,
|
||||||
log::*,
|
log::*,
|
||||||
rand::{thread_rng, Rng},
|
rand::{thread_rng, Rng},
|
||||||
rayon::{prelude::*, ThreadPool},
|
rayon::{prelude::*, ThreadPool},
|
||||||
|
@ -21,7 +22,7 @@ use {
|
||||||
recycler::Recycler,
|
recycler::Recycler,
|
||||||
sigverify,
|
sigverify,
|
||||||
},
|
},
|
||||||
solana_rayon_threadlimit::get_thread_count,
|
solana_rayon_threadlimit::get_max_thread_count,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
packet::Meta,
|
packet::Meta,
|
||||||
|
@ -32,7 +33,6 @@ use {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
cell::RefCell,
|
|
||||||
cmp,
|
cmp,
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
sync::{
|
sync::{
|
||||||
|
@ -44,11 +44,15 @@ use {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local!(static PAR_THREAD_POOL: RefCell<ThreadPool> = RefCell::new(rayon::ThreadPoolBuilder::new()
|
// get_max_thread_count to match number of threads in the old code.
|
||||||
.num_threads(get_thread_count())
|
// see: https://github.com/solana-labs/solana/pull/24853
|
||||||
|
lazy_static! {
|
||||||
|
static ref PAR_THREAD_POOL: ThreadPool = rayon::ThreadPoolBuilder::new()
|
||||||
|
.num_threads(get_max_thread_count())
|
||||||
.thread_name(|ix| format!("entry_{}", ix))
|
.thread_name(|ix| format!("entry_{}", ix))
|
||||||
.build()
|
.build()
|
||||||
.unwrap()));
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
pub type EntrySender = Sender<Vec<Entry>>;
|
pub type EntrySender = Sender<Vec<Entry>>;
|
||||||
pub type EntryReceiver = Receiver<Vec<Entry>>;
|
pub type EntryReceiver = Receiver<Vec<Entry>>;
|
||||||
|
@ -341,8 +345,7 @@ impl EntryVerificationState {
|
||||||
.expect("unwrap Arc")
|
.expect("unwrap Arc")
|
||||||
.into_inner()
|
.into_inner()
|
||||||
.expect("into_inner");
|
.expect("into_inner");
|
||||||
let res = PAR_THREAD_POOL.with(|thread_pool| {
|
let res = PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
hashes
|
hashes
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
|
@ -357,9 +360,7 @@ impl EntryVerificationState {
|
||||||
};
|
};
|
||||||
actual == expected
|
actual == expected
|
||||||
})
|
})
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
verify_check_time.stop();
|
verify_check_time.stop();
|
||||||
self.poh_duration_us += gpu_time_us + verify_check_time.as_us();
|
self.poh_duration_us += gpu_time_us + verify_check_time.as_us();
|
||||||
|
|
||||||
|
@ -381,8 +382,7 @@ pub fn verify_transactions(
|
||||||
entries: Vec<Entry>,
|
entries: Vec<Entry>,
|
||||||
verify: Arc<dyn Fn(VersionedTransaction) -> Result<SanitizedTransaction> + Send + Sync>,
|
verify: Arc<dyn Fn(VersionedTransaction) -> Result<SanitizedTransaction> + Send + Sync>,
|
||||||
) -> Result<Vec<EntryType>> {
|
) -> Result<Vec<EntryType>> {
|
||||||
PAR_THREAD_POOL.with(|thread_pool| {
|
PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
entries
|
entries
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|entry| {
|
.map(|entry| {
|
||||||
|
@ -400,7 +400,6 @@ pub fn verify_transactions(
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_verify_transactions(
|
pub fn start_verify_transactions(
|
||||||
|
@ -615,8 +614,7 @@ impl EntrySlice for [Entry] {
|
||||||
transactions: vec![],
|
transactions: vec![],
|
||||||
}];
|
}];
|
||||||
let entry_pairs = genesis.par_iter().chain(self).zip(self);
|
let entry_pairs = genesis.par_iter().chain(self).zip(self);
|
||||||
let res = PAR_THREAD_POOL.with(|thread_pool| {
|
let res = PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
entry_pairs.all(|(x0, x1)| {
|
entry_pairs.all(|(x0, x1)| {
|
||||||
let r = x1.verify(&x0.hash);
|
let r = x1.verify(&x0.hash);
|
||||||
if !r {
|
if !r {
|
||||||
|
@ -629,9 +627,7 @@ impl EntrySlice for [Entry] {
|
||||||
}
|
}
|
||||||
r
|
r
|
||||||
})
|
})
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let poh_duration_us = timing::duration_as_us(&now.elapsed());
|
let poh_duration_us = timing::duration_as_us(&now.elapsed());
|
||||||
EntryVerificationState {
|
EntryVerificationState {
|
||||||
verification_status: if res {
|
verification_status: if res {
|
||||||
|
@ -675,8 +671,7 @@ impl EntrySlice for [Entry] {
|
||||||
num_hashes.resize(aligned_len, 0);
|
num_hashes.resize(aligned_len, 0);
|
||||||
let num_hashes: Vec<_> = num_hashes.chunks(simd_len).collect();
|
let num_hashes: Vec<_> = num_hashes.chunks(simd_len).collect();
|
||||||
|
|
||||||
let res = PAR_THREAD_POOL.with(|thread_pool| {
|
let res = PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
hashes_chunked
|
hashes_chunked
|
||||||
.par_iter_mut()
|
.par_iter_mut()
|
||||||
.zip(num_hashes)
|
.zip(num_hashes)
|
||||||
|
@ -713,7 +708,6 @@ impl EntrySlice for [Entry] {
|
||||||
compare_hashes(hash, ref_entry)
|
compare_hashes(hash, ref_entry)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
|
||||||
});
|
});
|
||||||
let poh_duration_us = timing::duration_as_us(&now.elapsed());
|
let poh_duration_us = timing::duration_as_us(&now.elapsed());
|
||||||
EntryVerificationState {
|
EntryVerificationState {
|
||||||
|
@ -812,8 +806,7 @@ impl EntrySlice for [Entry] {
|
||||||
timing::duration_as_us(&gpu_wait.elapsed())
|
timing::duration_as_us(&gpu_wait.elapsed())
|
||||||
});
|
});
|
||||||
|
|
||||||
let verifications = PAR_THREAD_POOL.with(|thread_pool| {
|
let verifications = PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
self.into_par_iter()
|
self.into_par_iter()
|
||||||
.map(|entry| {
|
.map(|entry| {
|
||||||
let answer = entry.hash;
|
let answer = entry.hash;
|
||||||
|
@ -829,9 +822,7 @@ impl EntrySlice for [Entry] {
|
||||||
(action, answer)
|
(action, answer)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let device_verification_data = DeviceVerificationData::Gpu(GpuVerificationData {
|
let device_verification_data = DeviceVerificationData::Gpu(GpuVerificationData {
|
||||||
thread_h: Some(gpu_verify_thread),
|
thread_h: Some(gpu_verify_thread),
|
||||||
verifications: Some(verifications),
|
verifications: Some(verifications),
|
||||||
|
|
|
@ -28,7 +28,7 @@ use {
|
||||||
datapoint_debug, datapoint_error,
|
datapoint_debug, datapoint_error,
|
||||||
poh_timing_point::{send_poh_timing_point, PohTimingSender, SlotPohTimingInfo},
|
poh_timing_point::{send_poh_timing_point, PohTimingSender, SlotPohTimingInfo},
|
||||||
},
|
},
|
||||||
solana_rayon_threadlimit::get_thread_count,
|
solana_rayon_threadlimit::get_max_thread_count,
|
||||||
solana_runtime::hardened_unpack::{unpack_genesis_archive, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE},
|
solana_runtime::hardened_unpack::{unpack_genesis_archive, MAX_GENESIS_ARCHIVE_UNPACKED_SIZE},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
clock::{Slot, UnixTimestamp, DEFAULT_TICKS_PER_SECOND, MS_PER_TICK},
|
clock::{Slot, UnixTimestamp, DEFAULT_TICKS_PER_SECOND, MS_PER_TICK},
|
||||||
|
@ -75,17 +75,20 @@ pub use {
|
||||||
pub const BLOCKSTORE_DIRECTORY_ROCKS_LEVEL: &str = "rocksdb";
|
pub const BLOCKSTORE_DIRECTORY_ROCKS_LEVEL: &str = "rocksdb";
|
||||||
pub const BLOCKSTORE_DIRECTORY_ROCKS_FIFO: &str = "rocksdb_fifo";
|
pub const BLOCKSTORE_DIRECTORY_ROCKS_FIFO: &str = "rocksdb_fifo";
|
||||||
|
|
||||||
thread_local!(static PAR_THREAD_POOL: RefCell<ThreadPool> = RefCell::new(rayon::ThreadPoolBuilder::new()
|
// get_max_thread_count to match number of threads in the old code.
|
||||||
.num_threads(get_thread_count())
|
// see: https://github.com/solana-labs/solana/pull/24853
|
||||||
|
lazy_static! {
|
||||||
|
static ref PAR_THREAD_POOL: ThreadPool = rayon::ThreadPoolBuilder::new()
|
||||||
|
.num_threads(get_max_thread_count())
|
||||||
.thread_name(|ix| format!("blockstore_{}", ix))
|
.thread_name(|ix| format!("blockstore_{}", ix))
|
||||||
.build()
|
.build()
|
||||||
.unwrap()));
|
.unwrap();
|
||||||
|
static ref PAR_THREAD_POOL_ALL_CPUS: ThreadPool = rayon::ThreadPoolBuilder::new()
|
||||||
thread_local!(static PAR_THREAD_POOL_ALL_CPUS: RefCell<ThreadPool> = RefCell::new(rayon::ThreadPoolBuilder::new()
|
|
||||||
.num_threads(num_cpus::get())
|
.num_threads(num_cpus::get())
|
||||||
.thread_name(|ix| format!("blockstore_{}", ix))
|
.thread_name(|ix| format!("blockstore_{}", ix))
|
||||||
.build()
|
.build()
|
||||||
.unwrap()));
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
pub const MAX_REPLAY_WAKE_UP_SIGNALS: usize = 1;
|
pub const MAX_REPLAY_WAKE_UP_SIGNALS: usize = 1;
|
||||||
pub const MAX_COMPLETED_SLOTS_IN_CHANNEL: usize = 100_000;
|
pub const MAX_COMPLETED_SLOTS_IN_CHANNEL: usize = 100_000;
|
||||||
|
@ -2790,22 +2793,14 @@ impl Blockstore {
|
||||||
.map(|(_, end_index)| u64::from(*end_index) - start_index + 1)
|
.map(|(_, end_index)| u64::from(*end_index) - start_index + 1)
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
let entries: Result<Vec<Vec<Entry>>> = PAR_THREAD_POOL.with(|thread_pool| {
|
let entries: Result<Vec<Vec<Entry>>> = PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
completed_ranges
|
completed_ranges
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|(start_index, end_index)| {
|
.map(|(start_index, end_index)| {
|
||||||
self.get_entries_in_data_block(
|
self.get_entries_in_data_block(slot, *start_index, *end_index, Some(&slot_meta))
|
||||||
slot,
|
|
||||||
*start_index,
|
|
||||||
*end_index,
|
|
||||||
Some(&slot_meta),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let entries: Vec<Entry> = entries?.into_iter().flatten().collect();
|
let entries: Vec<Entry> = entries?.into_iter().flatten().collect();
|
||||||
Ok((entries, num_shreds, slot_meta.is_full()))
|
Ok((entries, num_shreds, slot_meta.is_full()))
|
||||||
}
|
}
|
||||||
|
@ -2935,23 +2930,15 @@ impl Blockstore {
|
||||||
}
|
}
|
||||||
let slot_meta = slot_meta.unwrap();
|
let slot_meta = slot_meta.unwrap();
|
||||||
|
|
||||||
let entries: Vec<Vec<Entry>> = PAR_THREAD_POOL_ALL_CPUS.with(|thread_pool| {
|
let entries: Vec<Vec<Entry>> = PAR_THREAD_POOL_ALL_CPUS.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
completed_ranges
|
completed_ranges
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|(start_index, end_index)| {
|
.map(|(start_index, end_index)| {
|
||||||
self.get_entries_in_data_block(
|
self.get_entries_in_data_block(slot, *start_index, *end_index, Some(&slot_meta))
|
||||||
slot,
|
|
||||||
*start_index,
|
|
||||||
*end_index,
|
|
||||||
Some(&slot_meta),
|
|
||||||
)
|
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
entries.into_iter().flatten().collect()
|
entries.into_iter().flatten().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ use {
|
||||||
solana_measure::measure::Measure,
|
solana_measure::measure::Measure,
|
||||||
solana_metrics::{datapoint_error, inc_new_counter_debug},
|
solana_metrics::{datapoint_error, inc_new_counter_debug},
|
||||||
solana_program_runtime::timings::{ExecuteTimingType, ExecuteTimings},
|
solana_program_runtime::timings::{ExecuteTimingType, ExecuteTimings},
|
||||||
solana_rayon_threadlimit::get_thread_count,
|
solana_rayon_threadlimit::{get_max_thread_count, get_thread_count},
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
accounts_background_service::AbsRequestSender,
|
accounts_background_service::AbsRequestSender,
|
||||||
accounts_db::{AccountShrinkThreshold, AccountsDbConfig},
|
accounts_db::{AccountShrinkThreshold, AccountsDbConfig},
|
||||||
|
@ -55,7 +55,6 @@ use {
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
cell::RefCell,
|
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
result,
|
result,
|
||||||
|
@ -94,12 +93,15 @@ impl BlockCostCapacityMeter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local!(static PAR_THREAD_POOL: RefCell<ThreadPool> = RefCell::new(rayon::ThreadPoolBuilder::new()
|
// get_max_thread_count to match number of threads in the old code.
|
||||||
.num_threads(get_thread_count())
|
// see: https://github.com/solana-labs/solana/pull/24853
|
||||||
|
lazy_static! {
|
||||||
|
static ref PAR_THREAD_POOL: ThreadPool = rayon::ThreadPoolBuilder::new()
|
||||||
|
.num_threads(get_max_thread_count())
|
||||||
.thread_name(|ix| format!("blockstore_processor_{}", ix))
|
.thread_name(|ix| format!("blockstore_processor_{}", ix))
|
||||||
.build()
|
.build()
|
||||||
.unwrap())
|
.unwrap();
|
||||||
);
|
}
|
||||||
|
|
||||||
fn first_err(results: &[Result<()>]) -> Result<()> {
|
fn first_err(results: &[Result<()>]) -> Result<()> {
|
||||||
for r in results {
|
for r in results {
|
||||||
|
@ -263,8 +265,7 @@ fn execute_batches_internal(
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
inc_new_counter_debug!("bank-par_execute_entries-count", batches.len());
|
inc_new_counter_debug!("bank-par_execute_entries-count", batches.len());
|
||||||
let (results, new_timings): (Vec<Result<()>>, Vec<ExecuteTimings>) =
|
let (results, new_timings): (Vec<Result<()>>, Vec<ExecuteTimings>) =
|
||||||
PAR_THREAD_POOL.with(|thread_pool| {
|
PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
batches
|
batches
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|batch| {
|
.map(|batch| {
|
||||||
|
@ -283,9 +284,7 @@ fn execute_batches_internal(
|
||||||
(result, timings)
|
(result, timings)
|
||||||
})
|
})
|
||||||
.unzip()
|
.unzip()
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
timings.saturating_add_in_place(ExecuteTimingType::TotalBatchesLen, batches.len() as u64);
|
timings.saturating_add_in_place(ExecuteTimingType::TotalBatchesLen, batches.len() as u64);
|
||||||
timings.saturating_add_in_place(ExecuteTimingType::NumExecuteBatches, 1);
|
timings.saturating_add_in_place(ExecuteTimingType::NumExecuteBatches, 1);
|
||||||
for timing in new_timings {
|
for timing in new_timings {
|
||||||
|
@ -546,7 +545,6 @@ pub struct ProcessOptions {
|
||||||
pub full_leader_cache: bool,
|
pub full_leader_cache: bool,
|
||||||
pub halt_at_slot: Option<Slot>,
|
pub halt_at_slot: Option<Slot>,
|
||||||
pub entry_callback: Option<ProcessCallback>,
|
pub entry_callback: Option<ProcessCallback>,
|
||||||
pub override_num_threads: Option<usize>,
|
|
||||||
pub new_hard_forks: Option<Vec<Slot>>,
|
pub new_hard_forks: Option<Vec<Slot>>,
|
||||||
pub debug_keys: Option<Arc<HashSet<Pubkey>>>,
|
pub debug_keys: Option<Arc<HashSet<Pubkey>>>,
|
||||||
pub account_indexes: AccountSecondaryIndexes,
|
pub account_indexes: AccountSecondaryIndexes,
|
||||||
|
@ -635,15 +633,6 @@ pub fn process_blockstore_from_root(
|
||||||
cache_block_meta_sender: Option<&CacheBlockMetaSender>,
|
cache_block_meta_sender: Option<&CacheBlockMetaSender>,
|
||||||
accounts_background_request_sender: &AbsRequestSender,
|
accounts_background_request_sender: &AbsRequestSender,
|
||||||
) -> result::Result<(), BlockstoreProcessorError> {
|
) -> result::Result<(), BlockstoreProcessorError> {
|
||||||
if let Some(num_threads) = opts.override_num_threads {
|
|
||||||
PAR_THREAD_POOL.with(|pool| {
|
|
||||||
*pool.borrow_mut() = rayon::ThreadPoolBuilder::new()
|
|
||||||
.num_threads(num_threads)
|
|
||||||
.build()
|
|
||||||
.unwrap()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Starting slot must be a root, and thus has no parents
|
// Starting slot must be a root, and thus has no parents
|
||||||
assert_eq!(bank_forks.read().unwrap().banks().len(), 1);
|
assert_eq!(bank_forks.read().unwrap().banks().len(), 1);
|
||||||
let bank = bank_forks.read().unwrap().root_bank();
|
let bank = bank_forks.read().unwrap().root_bank();
|
||||||
|
@ -2409,23 +2398,6 @@ pub mod tests {
|
||||||
assert_eq!(bank.tick_height(), 1);
|
assert_eq!(bank.tick_height(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_process_ledger_options_override_threads() {
|
|
||||||
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(123);
|
|
||||||
let (ledger_path, _blockhash) = create_new_tmp_ledger_auto_delete!(&genesis_config);
|
|
||||||
|
|
||||||
let blockstore = Blockstore::open(ledger_path.path()).unwrap();
|
|
||||||
let opts = ProcessOptions {
|
|
||||||
override_num_threads: Some(1),
|
|
||||||
accounts_db_test_hash_calculation: true,
|
|
||||||
..ProcessOptions::default()
|
|
||||||
};
|
|
||||||
test_process_blockstore(&genesis_config, &blockstore, &opts);
|
|
||||||
PAR_THREAD_POOL.with(|pool| {
|
|
||||||
assert_eq!(pool.borrow().current_num_threads(), 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_process_ledger_options_full_leader_cache() {
|
fn test_process_ledger_options_full_leader_cache() {
|
||||||
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(123);
|
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(123);
|
||||||
|
@ -2493,7 +2465,6 @@ pub mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
let opts = ProcessOptions {
|
let opts = ProcessOptions {
|
||||||
override_num_threads: Some(1),
|
|
||||||
entry_callback: Some(entry_callback),
|
entry_callback: Some(entry_callback),
|
||||||
accounts_db_test_hash_calculation: true,
|
accounts_db_test_hash_calculation: true,
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
|
|
|
@ -5,6 +5,7 @@ use {
|
||||||
},
|
},
|
||||||
shred_stats::ProcessShredsStats,
|
shred_stats::ProcessShredsStats,
|
||||||
},
|
},
|
||||||
|
lazy_static::lazy_static,
|
||||||
rayon::{prelude::*, ThreadPool},
|
rayon::{prelude::*, ThreadPool},
|
||||||
reed_solomon_erasure::{
|
reed_solomon_erasure::{
|
||||||
galois_8::Field,
|
galois_8::Field,
|
||||||
|
@ -14,14 +15,16 @@ use {
|
||||||
solana_measure::measure::Measure,
|
solana_measure::measure::Measure,
|
||||||
solana_rayon_threadlimit::get_thread_count,
|
solana_rayon_threadlimit::get_thread_count,
|
||||||
solana_sdk::{clock::Slot, signature::Keypair},
|
solana_sdk::{clock::Slot, signature::Keypair},
|
||||||
std::{cell::RefCell, fmt::Debug},
|
std::fmt::Debug,
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local!(static PAR_THREAD_POOL: RefCell<ThreadPool> = RefCell::new(rayon::ThreadPoolBuilder::new()
|
lazy_static! {
|
||||||
|
static ref PAR_THREAD_POOL: ThreadPool = rayon::ThreadPoolBuilder::new()
|
||||||
.num_threads(get_thread_count())
|
.num_threads(get_thread_count())
|
||||||
.thread_name(|ix| format!("shredder_{}", ix))
|
.thread_name(|ix| format!("shredder_{}", ix))
|
||||||
.build()
|
.build()
|
||||||
.unwrap()));
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
type ReedSolomon = reed_solomon_erasure::ReedSolomon<Field>;
|
type ReedSolomon = reed_solomon_erasure::ReedSolomon<Field>;
|
||||||
|
|
||||||
|
@ -138,8 +141,7 @@ impl Shredder {
|
||||||
shred.sign(keypair);
|
shred.sign(keypair);
|
||||||
shred
|
shred
|
||||||
};
|
};
|
||||||
let data_shreds: Vec<Shred> = PAR_THREAD_POOL.with(|thread_pool| {
|
let data_shreds: Vec<Shred> = PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
serialized_shreds
|
serialized_shreds
|
||||||
.par_chunks(payload_capacity)
|
.par_chunks(payload_capacity)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -148,7 +150,6 @@ impl Shredder {
|
||||||
make_data_shred(shred_index, shred_data)
|
make_data_shred(shred_index, shred_data)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
|
||||||
});
|
});
|
||||||
gen_data_time.stop();
|
gen_data_time.stop();
|
||||||
|
|
||||||
|
@ -170,8 +171,7 @@ impl Shredder {
|
||||||
}
|
}
|
||||||
let mut gen_coding_time = Measure::start("gen_coding_shreds");
|
let mut gen_coding_time = Measure::start("gen_coding_shreds");
|
||||||
// 1) Generate coding shreds
|
// 1) Generate coding shreds
|
||||||
let mut coding_shreds: Vec<_> = PAR_THREAD_POOL.with(|thread_pool| {
|
let mut coding_shreds: Vec<_> = PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
data_shreds
|
data_shreds
|
||||||
.par_chunks(MAX_DATA_SHREDS_PER_FEC_BLOCK as usize)
|
.par_chunks(MAX_DATA_SHREDS_PER_FEC_BLOCK as usize)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -196,18 +196,15 @@ impl Shredder {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
|
||||||
});
|
});
|
||||||
gen_coding_time.stop();
|
gen_coding_time.stop();
|
||||||
|
|
||||||
let mut sign_coding_time = Measure::start("sign_coding_shreds");
|
let mut sign_coding_time = Measure::start("sign_coding_shreds");
|
||||||
// 2) Sign coding shreds
|
// 2) Sign coding shreds
|
||||||
PAR_THREAD_POOL.with(|thread_pool| {
|
PAR_THREAD_POOL.install(|| {
|
||||||
thread_pool.borrow().install(|| {
|
|
||||||
coding_shreds.par_iter_mut().for_each(|coding_shred| {
|
coding_shreds.par_iter_mut().for_each(|coding_shred| {
|
||||||
coding_shred.sign(keypair);
|
coding_shred.sign(keypair);
|
||||||
})
|
})
|
||||||
})
|
|
||||||
});
|
});
|
||||||
sign_coding_time.stop();
|
sign_coding_time.stop();
|
||||||
|
|
||||||
|
|
|
@ -4292,6 +4292,7 @@ dependencies = [
|
||||||
"fs_extra",
|
"fs_extra",
|
||||||
"histogram",
|
"histogram",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"lru",
|
"lru",
|
||||||
"min-max-heap",
|
"min-max-heap",
|
||||||
|
@ -4353,6 +4354,7 @@ dependencies = [
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"dlopen",
|
"dlopen",
|
||||||
"dlopen_derive",
|
"dlopen_derive",
|
||||||
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
|
|
@ -16,3 +16,9 @@ lazy_static! {
|
||||||
pub fn get_thread_count() -> usize {
|
pub fn get_thread_count() -> usize {
|
||||||
*MAX_RAYON_THREADS
|
*MAX_RAYON_THREADS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only used in legacy code.
|
||||||
|
// Use get_thread_count instead in all new code.
|
||||||
|
pub fn get_max_thread_count() -> usize {
|
||||||
|
get_thread_count().saturating_mul(2)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue