-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: Block Import benchmarks and test helpers (#1274)
Related issues: - #1167 This PR adds benchmarking for block synchronization. Benchmarks simulate the import by using mock services that introduce artificial delays. Benchmarks are provisioned by reusing existing test types and mock ports. This PR refactors the existing back pressure tests to extract its test structures so that they can be reused in benchmarks. In a follow up PR, I will be refactoring the block import to use a single buffer and asynchronous tasks to perform header downloads. --------- Co-authored-by: Brandon Kite <brandonkite92@gmail.com>
- Loading branch information
Showing
18 changed files
with
501 additions
and
231 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
use criterion::{ | ||
criterion_group, | ||
criterion_main, | ||
measurement::WallTime, | ||
BenchmarkGroup, | ||
Criterion, | ||
}; | ||
use fuel_core_benches::import::{ | ||
provision_import_test, | ||
Durations, | ||
PressureImport, | ||
SharedCounts, | ||
}; | ||
use fuel_core_services::{ | ||
SharedMutex, | ||
StateWatcher, | ||
}; | ||
use fuel_core_sync::state::State; | ||
use std::time::Duration; | ||
use tokio::runtime::Runtime; | ||
|
||
async fn execute_import(import: PressureImport, shutdown: &mut StateWatcher) { | ||
import.import(shutdown).await.unwrap(); | ||
} | ||
|
||
fn name(n: u32, durations: Durations, buffer_size: usize) -> String { | ||
format!( | ||
"import {n} * {d_h}/{d_c}/{d_t}/{d_e} - {sz}", | ||
n = n, | ||
d_h = durations.headers.as_millis(), | ||
d_c = durations.consensus.as_millis(), | ||
d_t = durations.transactions.as_millis(), | ||
d_e = durations.executes.as_millis(), | ||
sz = buffer_size | ||
) | ||
} | ||
|
||
fn bench_imports(c: &mut Criterion) { | ||
let bench_import = |group: &mut BenchmarkGroup<WallTime>, | ||
n: u32, | ||
durations: Durations, | ||
batch_size: u32, | ||
buffer_size: usize| { | ||
let name = name(n, durations, buffer_size); | ||
group.bench_function(name, move |b| { | ||
let rt = Runtime::new().unwrap(); | ||
b.to_async(&rt).iter_custom(|iters| async move { | ||
let mut elapsed_time = Duration::default(); | ||
for _ in 0..iters { | ||
let shared_count = SharedCounts::new(Default::default()); | ||
let state = State::new(None, n); | ||
let shared_state = SharedMutex::new(state); | ||
let (import, _tx, mut shutdown) = provision_import_test( | ||
shared_count.clone(), | ||
shared_state, | ||
durations, | ||
batch_size, | ||
buffer_size, | ||
buffer_size, | ||
); | ||
import.notify_one(); | ||
let start = std::time::Instant::now(); | ||
execute_import(import, &mut shutdown).await; | ||
elapsed_time += start.elapsed(); | ||
} | ||
elapsed_time | ||
}) | ||
}); | ||
}; | ||
|
||
let mut group = c.benchmark_group("import"); | ||
|
||
let n = 100; | ||
let durations = Durations { | ||
headers: Duration::from_millis(5), | ||
consensus: Duration::from_millis(5), | ||
transactions: Duration::from_millis(5), | ||
executes: Duration::from_millis(10), | ||
}; | ||
|
||
// Header batch size = 10, header/txn buffer size = 10 | ||
bench_import(&mut group, n, durations, 10, 10); | ||
|
||
// Header batch size = 20, header/txn buffer size = 10 | ||
bench_import(&mut group, n, durations, 20, 10); | ||
|
||
// Header batch size = 50, header/txn buffer size = 10 | ||
bench_import(&mut group, n, durations, 20, 10); | ||
|
||
// Header batch size = 10, header/txn buffer size = 20 | ||
bench_import(&mut group, n, durations, 10, 20); | ||
|
||
// Header batch size = 10, header/txn buffer size = 50 | ||
bench_import(&mut group, n, durations, 10, 50); | ||
|
||
// Header batch size = 50, header/txn buffer size = 50 | ||
bench_import(&mut group, n, durations, 10, 20); | ||
} | ||
|
||
criterion_group!(benches, bench_imports); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use fuel_core_services::{ | ||
SharedMutex, | ||
StateWatcher, | ||
}; | ||
pub use fuel_core_sync::import::test_helpers::SharedCounts; | ||
use fuel_core_sync::{ | ||
import::{ | ||
test_helpers::{ | ||
PressureBlockImporter, | ||
PressureConsensus, | ||
PressurePeerToPeer, | ||
}, | ||
Import, | ||
}, | ||
state::State, | ||
Config, | ||
}; | ||
use std::{ | ||
sync::Arc, | ||
time::Duration, | ||
}; | ||
use tokio::sync::{ | ||
watch::Sender, | ||
Notify, | ||
}; | ||
|
||
pub type PressureImport = | ||
Import<PressurePeerToPeer, PressureBlockImporter, PressureConsensus>; | ||
|
||
#[derive(Default, Clone, Copy)] | ||
pub struct Durations { | ||
pub headers: Duration, | ||
pub consensus: Duration, | ||
pub transactions: Duration, | ||
pub executes: Duration, | ||
} | ||
|
||
pub fn provision_import_test( | ||
shared_count: SharedCounts, | ||
shared_state: SharedMutex<State>, | ||
input: Durations, | ||
header_batch_size: u32, | ||
max_header_batch_requests: usize, | ||
max_get_txns_requests: usize, | ||
) -> ( | ||
PressureImport, | ||
Sender<fuel_core_services::State>, | ||
StateWatcher, | ||
) { | ||
let shared_notify = Arc::new(Notify::new()); | ||
let params = Config { | ||
max_header_batch_requests, | ||
header_batch_size, | ||
max_get_txns_requests, | ||
}; | ||
let p2p = Arc::new(PressurePeerToPeer::new( | ||
shared_count.clone(), | ||
[input.headers, input.transactions], | ||
)); | ||
let executor = Arc::new(PressureBlockImporter::new( | ||
shared_count.clone(), | ||
input.executes, | ||
)); | ||
let consensus = Arc::new(PressureConsensus::new( | ||
shared_count.clone(), | ||
input.consensus, | ||
)); | ||
|
||
let (tx, shutdown) = tokio::sync::watch::channel(fuel_core_services::State::Started); | ||
let watcher = shutdown.into(); | ||
let import = Import::new( | ||
shared_state, | ||
shared_notify, | ||
params, | ||
p2p, | ||
executor, | ||
consensus, | ||
); | ||
(import, tx, watcher) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.