Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit 3216b14

Browse files
niklasad15chdn
authored andcommitted
ethcore/VerificationQueue don't spawn up extra worker-threads when explictly specified not to (#9620)
* VerificationQueue don't spawn up extra threads In the verification queue we spawn up worker threads to do the work. However, if `num-verifiers` is specified we still spawn the maximum number of threads which consume extra memory. There is one catch though when `--scale-verifiers` is specified then we can't do it because all threads are created upon initilization AFAIK. In my opinion, is doesn't to use both `num-verifiers` and `scale-verifiers` they are kind of contradictory! * Fix nits in logic and add tests for verification * refactor(verification queue) - rm hardcoded const * Address grumbles in new tests * Remove hardcoded `MAX_VERIFIERS` constant and replace it by relying entirely on `num_cpu` crate instead inorder to support CPUs that have more cores/logical cores
1 parent cc963d4 commit 3216b14

File tree

1 file changed

+70
-13
lines changed
  • ethcore/src/verification/queue

1 file changed

+70
-13
lines changed

ethcore/src/verification/queue/mod.rs

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ pub mod kind;
3939
const MIN_MEM_LIMIT: usize = 16384;
4040
const MIN_QUEUE_LIMIT: usize = 512;
4141

42-
// maximum possible number of verification threads.
43-
const MAX_VERIFIERS: usize = 8;
44-
4542
/// Type alias for block queue convenience.
4643
pub type BlockQueue = VerificationQueue<self::kind::Blocks>;
4744

@@ -85,7 +82,7 @@ impl Default for VerifierSettings {
8582
fn default() -> Self {
8683
VerifierSettings {
8784
scale_verifiers: false,
88-
num_verifiers: MAX_VERIFIERS,
85+
num_verifiers: ::num_cpus::get(),
8986
}
9087
}
9188
}
@@ -231,16 +228,24 @@ impl<K: Kind> VerificationQueue<K> {
231228
let empty = Arc::new(Condvar::new());
232229
let scale_verifiers = config.verifier_settings.scale_verifiers;
233230

234-
let num_cpus = ::num_cpus::get();
235-
let max_verifiers = cmp::min(num_cpus, MAX_VERIFIERS);
231+
let max_verifiers = ::num_cpus::get();
236232
let default_amount = cmp::max(1, cmp::min(max_verifiers, config.verifier_settings.num_verifiers));
233+
234+
// if `auto-scaling` is enabled spawn up extra threads as they might be needed
235+
// otherwise just spawn the number of threads specified by the config
236+
let number_of_threads = if scale_verifiers {
237+
max_verifiers
238+
} else {
239+
cmp::min(default_amount, max_verifiers)
240+
};
241+
237242
let state = Arc::new((Mutex::new(State::Work(default_amount)), Condvar::new()));
238-
let mut verifier_handles = Vec::with_capacity(max_verifiers);
243+
let mut verifier_handles = Vec::with_capacity(number_of_threads);
239244

240-
debug!(target: "verification", "Allocating {} verifiers, {} initially active", max_verifiers, default_amount);
245+
debug!(target: "verification", "Allocating {} verifiers, {} initially active", number_of_threads, default_amount);
241246
debug!(target: "verification", "Verifier auto-scaling {}", if scale_verifiers { "enabled" } else { "disabled" });
242247

243-
for i in 0..max_verifiers {
248+
for i in 0..number_of_threads {
244249
debug!(target: "verification", "Adding verification thread #{}", i);
245250

246251
let verification = verification.clone();
@@ -743,6 +748,13 @@ mod tests {
743748
BlockQueue::new(config, engine, IoChannel::disconnected(), true)
744749
}
745750

751+
fn get_test_config(num_verifiers: usize, is_auto_scale: bool) -> Config {
752+
let mut config = Config::default();
753+
config.verifier_settings.num_verifiers = num_verifiers;
754+
config.verifier_settings.scale_verifiers = is_auto_scale;
755+
config
756+
}
757+
746758
fn new_unverified(bytes: Bytes) -> Unverified {
747759
Unverified::from_rlp(bytes).expect("Should be valid rlp")
748760
}
@@ -843,12 +855,11 @@ mod tests {
843855

844856
#[test]
845857
fn scaling_limits() {
846-
use super::MAX_VERIFIERS;
847-
858+
let max_verifiers = ::num_cpus::get();
848859
let queue = get_test_queue(true);
849-
queue.scale_verifiers(MAX_VERIFIERS + 1);
860+
queue.scale_verifiers(max_verifiers + 1);
850861

851-
assert!(queue.num_verifiers() < MAX_VERIFIERS + 1);
862+
assert!(queue.num_verifiers() < max_verifiers + 1);
852863

853864
queue.scale_verifiers(0);
854865

@@ -877,4 +888,50 @@ mod tests {
877888
queue.collect_garbage();
878889
assert_eq!(queue.num_verifiers(), 1);
879890
}
891+
892+
#[test]
893+
fn worker_threads_honor_specified_number_without_scaling() {
894+
let spec = Spec::new_test();
895+
let engine = spec.engine;
896+
let config = get_test_config(1, false);
897+
let queue = BlockQueue::new(config, engine, IoChannel::disconnected(), true);
898+
899+
assert_eq!(queue.num_verifiers(), 1);
900+
}
901+
902+
#[test]
903+
fn worker_threads_specified_to_zero_should_set_to_one() {
904+
let spec = Spec::new_test();
905+
let engine = spec.engine;
906+
let config = get_test_config(0, false);
907+
let queue = BlockQueue::new(config, engine, IoChannel::disconnected(), true);
908+
909+
assert_eq!(queue.num_verifiers(), 1);
910+
}
911+
912+
#[test]
913+
fn worker_threads_should_only_accept_max_number_cpus() {
914+
let spec = Spec::new_test();
915+
let engine = spec.engine;
916+
let config = get_test_config(10_000, false);
917+
let queue = BlockQueue::new(config, engine, IoChannel::disconnected(), true);
918+
let num_cpus = ::num_cpus::get();
919+
920+
assert_eq!(queue.num_verifiers(), num_cpus);
921+
}
922+
923+
#[test]
924+
fn worker_threads_scaling_with_specifed_num_of_workers() {
925+
let num_cpus = ::num_cpus::get();
926+
// only run the test with at least 2 CPUs
927+
if num_cpus > 1 {
928+
let spec = Spec::new_test();
929+
let engine = spec.engine;
930+
let config = get_test_config(num_cpus - 1, true);
931+
let queue = BlockQueue::new(config, engine, IoChannel::disconnected(), true);
932+
queue.scale_verifiers(num_cpus);
933+
934+
assert_eq!(queue.num_verifiers(), num_cpus);
935+
}
936+
}
880937
}

0 commit comments

Comments
 (0)