| 1 | |
| 2 | |
| 3 |
|
| 4 | use kernel::alloc::flags::GFP_KERNEL;
|
| 5 | use kernel::bindings;
|
| 6 | use kernel::bitmap::BitmapVec;
|
| 7 | use kernel::error::{code, Result};
|
| 8 | use kernel::prelude::module;
|
| 9 | use kernel::time::{Instant, Monotonic};
|
| 10 | use kernel::ThisModule;
|
| 11 | use kernel::{pr_cont, pr_err};
|
| 12 |
|
| 13 | const BITMAP_LEN: usize = 4096 * 8 * 10;
|
| 14 | |
| 15 | const SPARSENESS: usize = 500;
|
| 16 |
|
| 17 | |
| 18 | struct Benchmark();
|
| 19 |
|
| 20 | fn test_next_bit(bitmap: &BitmapVec) {
|
| 21 | let time = Instant::<Monotonic>::now();
|
| 22 | let mut cnt = 0;
|
| 23 | let mut i = 0;
|
| 24 |
|
| 25 | while let Some(index) = bitmap.next_bit(i) {
|
| 26 | cnt += 1;
|
| 27 | i = index + 1;
|
| 28 | |
| 29 | if i == BITMAP_LEN {
|
| 30 | break;
|
| 31 | }
|
| 32 | }
|
| 33 |
|
| 34 | let delta = time.elapsed();
|
| 35 | pr_cont!(
|
| 36 | "\nnext_bit: {:18} ns, {:6} iterations",
|
| 37 | delta.as_nanos(),
|
| 38 | cnt
|
| 39 | );
|
| 40 | }
|
| 41 |
|
| 42 | fn test_next_zero_bit(bitmap: &BitmapVec) {
|
| 43 | let time = Instant::<Monotonic>::now();
|
| 44 | let mut cnt = 0;
|
| 45 | let mut i = 0;
|
| 46 |
|
| 47 | while let Some(index) = bitmap.next_zero_bit(i) {
|
| 48 | cnt += 1;
|
| 49 | i = index + 1;
|
| 50 | |
| 51 | if i == BITMAP_LEN {
|
| 52 | break;
|
| 53 | }
|
| 54 | }
|
| 55 |
|
| 56 | let delta = time.elapsed();
|
| 57 | pr_cont!(
|
| 58 | "\nnext_zero_bit: {:18} ns, {:6} iterations",
|
| 59 | delta.as_nanos(),
|
| 60 | cnt
|
| 61 | );
|
| 62 | }
|
| 63 |
|
| 64 | fn find_bit_test() {
|
| 65 | pr_err!("Benchmark");
|
| 66 | pr_cont!("\nStart testing find_bit() Rust with random-filled bitmap");
|
| 67 |
|
| 68 | let mut bitmap = BitmapVec::new(BITMAP_LEN, GFP_KERNEL).expect("alloc bitmap failed");
|
| 69 | bitmap.fill_random();
|
| 70 |
|
| 71 | test_next_bit(&bitmap);
|
| 72 | test_next_zero_bit(&bitmap);
|
| 73 |
|
| 74 | pr_cont!("\nStart testing find_bit() Rust with sparse bitmap");
|
| 75 |
|
| 76 | let mut bitmap = BitmapVec::new(BITMAP_LEN, GFP_KERNEL).expect("alloc sparse bitmap failed");
|
| 77 | let nbits = BITMAP_LEN / SPARSENESS;
|
| 78 | for _i in 0..nbits {
|
| 79 | |
| 80 | let bit =
|
| 81 | unsafe { bindings::__get_random_u32_below(BITMAP_LEN.try_into().unwrap()) as usize };
|
| 82 | bitmap.set_bit(bit);
|
| 83 | }
|
| 84 |
|
| 85 | test_next_bit(&bitmap);
|
| 86 | test_next_zero_bit(&bitmap);
|
| 87 | pr_cont!("\n");
|
| 88 | }
|
| 89 |
|
| 90 | impl kernel::Module for Benchmark {
|
| 91 | fn init(_module: &'static ThisModule) -> Result<Self> {
|
| 92 | find_bit_test();
|
| 93 | |
| 94 | Err(code::EINVAL)
|
| 95 | }
|
| 96 | }
|
| 97 |
|
| 98 | module! {
|
| 99 | type: Benchmark,
|
| 100 | name: "find_bit_benchmark_rust",
|
| 101 | authors: ["Burak Emir <[email protected]>"],
|
| 102 | description: "Module with benchmark for bitmap Rust API",
|
| 103 | license: "GPL v2",
|
| 104 | }
|