mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
performance-metrics: Add qcow2 fsync micro benchmark
Add micro_bench_qcow_fsync which writes num_ops clusters into an empty qcow2 image to dirty L2 and refcount metadata then times a single fsync call that flushes all dirty tables to disk. This isolates the metadata flush cost which scales with the number of dirty L2 table entries and refcount blocks. Two TEST_LIST entries: micro_block_qcow_fsync_64_us and micro_block_qcow_fsync_256_us with 64 and 256 cluster workloads. Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
committed by
Rob Bradford
parent
c3312dca3f
commit
e802c0d8b9
@@ -378,7 +378,7 @@ mod adjuster {
|
||||
}
|
||||
}
|
||||
|
||||
const TEST_LIST: [PerformanceTest; 68] = [
|
||||
const TEST_LIST: [PerformanceTest; 70] = [
|
||||
PerformanceTest {
|
||||
name: "boot_time_ms",
|
||||
func_ptr: performance_boot_time,
|
||||
@@ -1325,6 +1325,30 @@ const TEST_LIST: [PerformanceTest; 68] = [
|
||||
},
|
||||
unit_adjuster: adjuster::s_to_us,
|
||||
},
|
||||
PerformanceTest {
|
||||
name: "micro_block_qcow_fsync_128_us",
|
||||
func_ptr: micro_bench_block::micro_bench_qcow_fsync,
|
||||
control: PerformanceTestControl {
|
||||
test_timeout: 10,
|
||||
test_iterations: 20,
|
||||
warmup_iterations: 5,
|
||||
num_ops: Some(128),
|
||||
..PerformanceTestControl::default()
|
||||
},
|
||||
unit_adjuster: adjuster::s_to_us,
|
||||
},
|
||||
PerformanceTest {
|
||||
name: "micro_block_qcow_fsync_256_us",
|
||||
func_ptr: micro_bench_block::micro_bench_qcow_fsync,
|
||||
control: PerformanceTestControl {
|
||||
test_timeout: 10,
|
||||
test_iterations: 20,
|
||||
warmup_iterations: 5,
|
||||
num_ops: Some(256),
|
||||
..PerformanceTestControl::default()
|
||||
},
|
||||
unit_adjuster: adjuster::s_to_us,
|
||||
},
|
||||
];
|
||||
|
||||
fn run_test_with_timeout(
|
||||
|
||||
@@ -132,3 +132,33 @@ pub fn micro_bench_qcow_punch_hole(control: &PerformanceTestControl) -> f64 {
|
||||
|
||||
elapsed
|
||||
}
|
||||
|
||||
/// Write num_ops clusters into an empty qcow2 image to dirty L2 and
|
||||
/// refcount metadata, then time a single fsync that flushes all dirty
|
||||
/// tables to disk.
|
||||
///
|
||||
/// This isolates the metadata flush cost which scales with the number
|
||||
/// of dirty L2 table entries and refcount blocks.
|
||||
///
|
||||
/// Returns the fsync wall clock time in seconds.
|
||||
pub fn micro_bench_qcow_fsync(control: &PerformanceTestControl) -> f64 {
|
||||
let num_ops = control.num_ops.expect("num_ops required") as usize;
|
||||
let (_tmp, disk) = util::empty_qcow_tempfile(num_ops);
|
||||
let mut async_io = disk.new_async_io(1).expect("new_async_io failed");
|
||||
|
||||
// Write num_ops clusters to dirty L2 and refcount metadata.
|
||||
let buf = vec![0xA5u8; QCOW_CLUSTER_SIZE as usize];
|
||||
let iovec = write_iovec(&buf);
|
||||
submit_writes(async_io.as_mut(), num_ops, QCOW_CLUSTER_SIZE, &[iovec]);
|
||||
// Drain write completions.
|
||||
drain_completions(async_io.as_mut(), num_ops);
|
||||
|
||||
// Time the flush.
|
||||
let start = Instant::now();
|
||||
async_io.fsync(Some(num_ops as u64)).expect("fsync failed");
|
||||
let elapsed = start.elapsed().as_secs_f64();
|
||||
|
||||
drain_completions(async_io.as_mut(), 1);
|
||||
|
||||
elapsed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user