1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
use criterion::{black_box, BatchSize, Criterion};
use virtio_queue::{Queue, QueueOwnedT, QueueT};
use vm_memory::{GuestAddress, GuestMemory, GuestMemoryMmap};
use virtio_queue::mock::MockSplitQueue;
pub fn benchmark_queue(c: &mut Criterion) {
fn walk_queue<M: GuestMemory>(q: &mut Queue, mem: &M) -> (usize, usize) {
let mut num_chains = 0;
let mut num_descriptors = 0;
q.iter(mem).unwrap().for_each(|chain| {
num_chains += 1;
chain.for_each(|_| num_descriptors += 1);
});
(num_chains, num_descriptors)
}
fn bench_queue<S, R>(c: &mut Criterion, bench_name: &str, setup: S, mut routine: R)
where
S: FnMut() -> Queue + Clone,
R: FnMut(Queue),
{
c.bench_function(bench_name, move |b| {
b.iter_batched(
setup.clone(),
|q| routine(black_box(q)),
BatchSize::SmallInput,
)
});
}
let mem = GuestMemoryMmap::<()>::from_ranges(&[(GuestAddress(0x0), 0x1_0000_0000)]).unwrap();
let queue_with_chains = |num_chains, len, indirect| {
let mut mq = MockSplitQueue::new(&mem, 256);
for _ in 0..num_chains {
if indirect {
mq.add_indirect_chain(len).unwrap();
} else {
mq.add_chain(len).unwrap();
}
}
mq.create_queue().unwrap()
};
let empty_queue = || {
let mq = MockSplitQueue::new(&mem, 256);
mq.create_queue().unwrap()
};
for indirect in [false, true].iter().copied() {
bench_queue(
c,
&format!("single chain (indirect={})", indirect),
|| queue_with_chains(1, 128, indirect),
|mut q| {
let (num_chains, num_descriptors) = walk_queue(&mut q, &mem);
assert_eq!(num_chains, 1);
assert_eq!(num_descriptors, 128);
},
);
bench_queue(
c,
&format!("multiple chains (indirect={})", indirect),
|| queue_with_chains(128, 1, indirect),
|mut q| {
let (num_chains, num_descriptors) = walk_queue(&mut q, &mem);
assert_eq!(num_chains, 128);
assert_eq!(num_descriptors, 128);
},
);
}
bench_queue(c, "add used", empty_queue, |mut q| {
for _ in 0..128 {
q.add_used(&mem, 123, 0x1000).unwrap();
}
});
}
|