Skip to content

Commit

Permalink
refactor(bench)!: move benchmarking facilities to their own crate
Browse files Browse the repository at this point in the history
  • Loading branch information
ROMemories committed Apr 8, 2024
1 parent a17549f commit 5ced699
Show file tree
Hide file tree
Showing 15 changed files with 130 additions and 45 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ jobs:
- name: clippy
uses: clechasseur/rs-clippy-check@v3
with:
args: --verbose --locked -p riot-rs-embassy
args: --verbose --locked -p riot-rs-embassy -p riot-rs-bench

# TODO: we'll eventually want to enable relevant features
- name: "rustdoc"
run: cargo rustdoc -p riot-rs --features no-boards -- -D warnings
run: cargo rustdoc -p riot-rs --features no-boards,bench -- -D warnings

- name: rustfmt
run: cargo fmt --check --all
Expand Down
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"src/lib/rbi",
"src/lib/ringbuffer",
"src/riot-rs",
"src/riot-rs-bench",
"src/riot-rs-boards",
"src/riot-rs-boards/nrf52",
"src/riot-rs-boards/nrf52840dk",
Expand Down Expand Up @@ -51,6 +52,7 @@ esp-wifi = { git = "https://github.com/kaspar030/esp-wifi", branch = "update-esp
linkme = { version = "0.3.21", features = ["used_linker"] }

riot-rs = { path = "src/riot-rs", default-features = false }
riot-rs-bench = { path = "src/riot-rs-bench", default-features = false }
riot-rs-boards = { path = "src/riot-rs-boards", default-features = false }
riot-rs-debug = { path = "src/riot-rs-debug", default-features = false }
riot-rs-rt = { path = "src/riot-rs-rt" }
Expand Down
2 changes: 1 addition & 1 deletion examples/benchmark/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ edition = "2021"
publish = false

[dependencies]
riot-rs = { path = "../../src/riot-rs", features = ["threading"] }
riot-rs = { path = "../../src/riot-rs", features = ["bench", "threading"] }
riot-rs-boards = { path = "../../src/riot-rs-boards" }
2 changes: 1 addition & 1 deletion examples/benchmark/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use riot_rs::debug::println;

#[riot_rs::thread(autostart)]
fn main() {
match riot_rs::rt::benchmark(10000, || {
match riot_rs::bench::benchmark(10000, || {
//
}) {
Ok(ticks) => {
Expand Down
15 changes: 15 additions & 0 deletions src/riot-rs-bench/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "riot-rs-bench"
version.workspace = true
authors.workspace = true
edition.workspace = true
repository.workspace = true

[lints]
workspace = true

[dependencies]
cfg-if = { workspace = true }

[target.'cfg(context = "cortex-m")'.dependencies]
cortex-m = { workspace = true, features = ["critical-section-single-core"] }
36 changes: 36 additions & 0 deletions src/riot-rs-bench/src/cortexm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use cortex_m::{
peripheral::{syst::SystClkSource, SYST},
Peripherals,
};

use crate::Error;

#[allow(missing_docs)]
pub fn benchmark<F: Fn() -> ()>(iterations: usize, f: F) -> Result<usize, Error> {
let mut p = unsafe { Peripherals::steal() };
//
p.SCB.clear_sleepdeep();

//
p.SYST.set_clock_source(SystClkSource::Core);
p.SYST.set_reload(0x00FFFFFF);
p.SYST.clear_current();
p.SYST.enable_counter();

// Wait for the system timer to be ready
while SYST::get_current() == 0 {}

let before = SYST::get_current();

for _ in 0..iterations {
f();
}

let total = before - SYST::get_current();

if p.SYST.has_wrapped() {
Err(Error::SystemTimerWrapped)
} else {
Ok(total as usize / iterations)
}
}
55 changes: 55 additions & 0 deletions src/riot-rs-bench/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//! Provides on-board benchmarking facilities.

#![cfg_attr(not(test), no_std)]
#![feature(error_in_core)]
#![deny(clippy::pedantic)]
#![deny(missing_docs)]

cfg_if::cfg_if! {
if #[cfg(context = "cortex-m")] {
mod cortexm;
use cortexm as bench;
}
else if #[cfg(context = "riot-rs")] {
// When run with laze but the architecture is not supported
compile_error!("benchmarking is not supported for this architecture");
} else {
// Provide a default bench module, for arch-independent tooling
mod bench {
use crate::Error;

/// Benchmarks "time" required to run the provided function.
///
/// Runs the provided function `iterations` times, and returns the mean number of system timer
/// increments per iteration.
///
/// # Errors
///
/// Returns [`Error::SystemTimerWrapped`] if the system timer counter has wrapped when
/// benchmarking.
#[allow(unused_variables)]
pub fn benchmark<F: Fn()>(iterations: usize, f: F) -> Result<usize, Error> {
unimplemented!();
}
}
}
}

pub use bench::benchmark;

/// Possible errors happening when benchmarking.
#[derive(Debug)]
pub enum Error {
/// The system timer wrapped when benchmarking.
SystemTimerWrapped,
}

impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::SystemTimerWrapped => write!(f, "system timer wrapped"),
}
}
}

impl core::error::Error for Error {}
31 changes: 0 additions & 31 deletions src/riot-rs-rt/src/cortexm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,34 +208,3 @@ pub fn init() {
p.SCB.set_priority(SystemHandler::PendSV, 0xFF);
}
}

pub fn benchmark<F: Fn() -> ()>(iterations: usize, f: F) -> core::result::Result<usize, ()> {
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::Peripherals;

let mut p = unsafe { Peripherals::steal() };
//
p.SCB.clear_sleepdeep();

//
p.SYST.set_clock_source(SystClkSource::Core);
p.SYST.set_reload(0x00FFFFFF);
p.SYST.clear_current();
p.SYST.enable_counter();

while cortex_m::peripheral::SYST::get_current() == 0 {}

let before = cortex_m::peripheral::SYST::get_current();

for _ in 0..iterations {
f();
}

let total = before - cortex_m::peripheral::SYST::get_current();

if p.SYST.has_wrapped() {
Err(())
} else {
Ok((total) as usize / iterations)
}
}
4 changes: 0 additions & 4 deletions src/riot-rs-rt/src/esp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,3 @@ fn main() -> ! {
}

pub fn init() {}

pub fn benchmark<F: Fn() -> ()>(_iterations: usize, _f: F) -> core::result::Result<usize, ()> {
unimplemented!()
}
5 changes: 0 additions & 5 deletions src/riot-rs-rt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,10 @@ cfg_if::cfg_if! {
mod arch {
#[cfg_attr(not(context = "riot-rs"), allow(dead_code))]
pub fn init() {}
pub fn benchmark<F: Fn()>(_iterations: usize, _f: F) -> core::result::Result<usize, ()> {
unimplemented!();
}
}
}
}

pub use arch::benchmark;

const ISR_STACKSIZE: usize =
riot_rs_utils::usize_from_env_or!("CONFIG_ISR_STACKSIZE", 8192, "ISR stack size (in bytes)");

Expand Down
3 changes: 3 additions & 0 deletions src/riot-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ workspace = true
[dependencies]
document-features = { workspace = true }
linkme = { workspace = true }
riot-rs-bench = { workspace = true, optional = true }
riot-rs-boards = { path = "../riot-rs-boards" }
riot-rs-buildinfo = { path = "../riot-rs-buildinfo" }
riot-rs-debug = { workspace = true }
Expand Down Expand Up @@ -74,6 +75,8 @@ wifi-esp = ["riot-rs-embassy/wifi-esp"]
## Enables the debug console, required to use
## [`println!`](riot_rs_debug::println).
debug-console = ["riot-rs-rt/debug-console"]
## Enables benchmarking facilities.
bench = ["dep:riot-rs-bench"]
## Prints nothing in case of panics (may help reduce binary size).
silent-panic = ["riot-rs-rt/silent-panic"]
## Allows to have no boards selected, useful to run target-independent tooling.
Expand Down
4 changes: 4 additions & 0 deletions src/riot-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#![no_std]
#![feature(doc_cfg)]

#[cfg(feature = "bench")]
#[doc(cfg(feature = "bench"))]
#[doc(inline)]
pub use riot_rs_bench as bench;
pub use riot_rs_buildinfo as buildinfo;
pub use riot_rs_debug as debug;
pub use riot_rs_embassy::{self as embassy, define_peripherals, group_peripherals};
Expand Down
1 change: 1 addition & 0 deletions tests/benchmarks/bench_sched_yield/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ publish = false

[dependencies]
riot-rs = { workspace = true, default-features = true, features = [
"bench",
"threading",
] }
riot-rs-boards = { workspace = true }
2 changes: 1 addition & 1 deletion tests/benchmarks/bench_sched_yield/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use riot_rs::{debug::println, thread};

#[riot_rs::thread(autostart)]
fn thread0() {
match riot_rs::rt::benchmark(10000, || thread::yield_same()) {
match riot_rs::bench::benchmark(10000, || thread::yield_same()) {
Ok(ticks) => {
println!(
"took {} ticks per iteration ({} per context switch)",
Expand Down

0 comments on commit 5ced699

Please sign in to comment.