| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- // SPDX-License-Identifier: GPL-2.0
- //! Benchmark for find_bit-like methods in Bitmap Rust API.
- use kernel::alloc::flags::GFP_KERNEL;
- use kernel::bindings;
- use kernel::bitmap::BitmapVec;
- use kernel::error::{code, Result};
- use kernel::prelude::module;
- use kernel::time::{Instant, Monotonic};
- use kernel::ThisModule;
- use kernel::{pr_cont, pr_err};
- const BITMAP_LEN: usize = 4096 * 8 * 10;
- // Reciprocal of the fraction of bits that are set in sparse bitmap.
- const SPARSENESS: usize = 500;
- /// Test module that benchmarks performance of traversing bitmaps.
- struct Benchmark();
- fn test_next_bit(bitmap: &BitmapVec) {
- let time = Instant::<Monotonic>::now();
- let mut cnt = 0;
- let mut i = 0;
- while let Some(index) = bitmap.next_bit(i) {
- cnt += 1;
- i = index + 1;
- // CONFIG_RUST_BITMAP_HARDENED enforces strict bounds.
- if i == BITMAP_LEN {
- break;
- }
- }
- let delta = time.elapsed();
- pr_cont!(
- "\nnext_bit: {:18} ns, {:6} iterations",
- delta.as_nanos(),
- cnt
- );
- }
- fn test_next_zero_bit(bitmap: &BitmapVec) {
- let time = Instant::<Monotonic>::now();
- let mut cnt = 0;
- let mut i = 0;
- while let Some(index) = bitmap.next_zero_bit(i) {
- cnt += 1;
- i = index + 1;
- // CONFIG_RUST_BITMAP_HARDENED enforces strict bounds.
- if i == BITMAP_LEN {
- break;
- }
- }
- let delta = time.elapsed();
- pr_cont!(
- "\nnext_zero_bit: {:18} ns, {:6} iterations",
- delta.as_nanos(),
- cnt
- );
- }
- fn find_bit_test() {
- pr_err!("Benchmark");
- pr_cont!("\nStart testing find_bit() Rust with random-filled bitmap");
- let mut bitmap = BitmapVec::new(BITMAP_LEN, GFP_KERNEL).expect("alloc bitmap failed");
- bitmap.fill_random();
- test_next_bit(&bitmap);
- test_next_zero_bit(&bitmap);
- pr_cont!("\nStart testing find_bit() Rust with sparse bitmap");
- let mut bitmap = BitmapVec::new(BITMAP_LEN, GFP_KERNEL).expect("alloc sparse bitmap failed");
- let nbits = BITMAP_LEN / SPARSENESS;
- for _i in 0..nbits {
- // SAFETY: __get_random_u32_below is safe to call with any u32 argument.
- let bit =
- unsafe { bindings::__get_random_u32_below(BITMAP_LEN.try_into().unwrap()) as usize };
- bitmap.set_bit(bit);
- }
- test_next_bit(&bitmap);
- test_next_zero_bit(&bitmap);
- pr_cont!("\n");
- }
- impl kernel::Module for Benchmark {
- fn init(_module: &'static ThisModule) -> Result<Self> {
- find_bit_test();
- // Return error so test module can be inserted again without rmmod.
- Err(code::EINVAL)
- }
- }
- module! {
- type: Benchmark,
- name: "find_bit_benchmark_rust",
- authors: ["Burak Emir <bqe@google.com>"],
- description: "Module with benchmark for bitmap Rust API",
- license: "GPL v2",
- }
|