add benchmarks. this commit exhibits a mysterious problem with Lookup API

This commit is contained in:
bunnie 2021-01-22 04:11:02 +08:00
parent 53dfda13bf
commit 31e58c3337
10 changed files with 360 additions and 3 deletions

26
Cargo.lock generated
View file

@ -59,6 +59,32 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "benchmark"
version = "0.1.0"
dependencies = [
"benchmark-target",
"blitstr-ref",
"graphics-server",
"log",
"log-server",
"ticktimer-server",
"utralib",
"xous",
"xous-names",
]
[[package]]
name = "benchmark-target"
version = "0.1.0"
dependencies = [
"log",
"log-server",
"utralib",
"xous",
"xous-names",
]
[[package]]
name = "bitflags"
version = "1.2.1"

View file

@ -14,6 +14,8 @@ members = [
"services/keyboard",
"services/trng",
"services/gam",
"services/benchmark",
"services/benchmark-target",
"svd2utra",
"xtask",
"imports/blitstr-ref",
@ -32,7 +34,9 @@ default-members = [
"services/trng",
"services/gam",
"imports/blitstr-ref",
"imports/com_rs-ref"
"imports/com_rs-ref",
"services/benchmark",
"services/benchmark-target",
]
# These packages have custom RUSTFLAGS, so if they

View file

@ -0,0 +1,20 @@
[package]
name = "benchmark-target"
version = "0.1.0"
authors = ["bunnie <bunnie@kosagi.com>"]
edition = "2018"
description = "Benchmark target for Xous"
[dependencies]
xous = { path = "../../xous-rs" }
xous-names = { path = "../xous-names" }
log-server = { path = "../log-server" }
log = "0.4"
[target.'cfg(not(any(windows,unix)))'.dependencies]
utralib = { path = "../../utralib"}
[features]
debugprint = []
# default = ["debugprint"] # "debugprint"
default = []

View file

@ -0,0 +1,37 @@
use xous::{Message, ScalarMessage};
use xous_names::api::Lookup;
#[allow(dead_code)]
#[derive(Debug)]
pub enum Opcode {
TestScalar(u32),
TestMemory(Lookup),
}
impl core::convert::TryFrom<& Message> for Opcode {
type Error = &'static str;
fn try_from(message: & Message) -> Result<Self, Self::Error> {
match message {
Message::BlockingScalar(m) => match m.id {
0 => Ok(Opcode::TestScalar(m.arg1 as u32)),
_ => Err("BENCHMARK-TARGET api: unknown BlockingScalar ID"),
},
_ => Err("BENCHMARK-TARGET api: unhandled message type"),
}
}
}
impl Into<Message> for Opcode {
fn into(self) -> Message {
match self {
Opcode::TestScalar(count) => Message::BlockingScalar(ScalarMessage {
id: 0,
arg1: count as usize,
arg2: 0,
arg3: 0,
arg4: 0,
}),
_ => panic!("GFX api: Opcode type not handled by Into(), maybe you meant to use a helper method?"),
}
}
}

View file

@ -0,0 +1,23 @@
#![cfg_attr(target_os = "none", no_std)]
pub mod api;
use xous::{CID, send_message};
use xous_names::api::Lookup;
use xous::ipc::Sendable;
pub fn test_scalar(cid: CID, testvar: u32) -> Result<u32, xous::Error> {
let response = send_message(cid, api::Opcode::TestScalar(testvar).into())?;
if let xous::Result::Scalar1(r) = response {
Ok(r as u32)
} else {
panic!("unexpected return value: {:#?}", response);
}
}
pub fn test_memory(cid: CID, testvar: u32) -> Result<u32, xous::Error> {
let reg = Lookup::new();
let mut sendable_reg = Sendable::new(reg).expect("can't create test structure");
sendable_reg.challenge[0] = testvar;
sendable_reg.lend_mut(cid, 0).expect("test failure");
Ok(sendable_reg.challenge[0])
}

View file

@ -0,0 +1,37 @@
#![cfg_attr(target_os = "none", no_std)]
#![cfg_attr(target_os = "none", no_main)]
mod api;
use api::*;
use xous_names::api::Lookup;
use core::convert::TryFrom;
use log::{error, info};
#[xous::xous_main]
fn xmain() -> ! {
log_server::init_wait().unwrap();
let bench_sid = xous_names::register_name(xous::names::SERVER_NAME_BENCHMARK).expect("BENCHTARGET: can't register server");
info!("BENCHTARGET: registered with NS -- {:?}", bench_sid);
loop {
let envelope = xous::receive_message(bench_sid).unwrap();
if let Ok(opcode) = Opcode::try_from(&envelope.body) {
match opcode {
Opcode::TestScalar(val) => {
xous::return_scalar(envelope.sender, (val + 1) as usize)
.expect("BENCHTARGET: couldn't return TestScalar request");
},
_ => error!("BENCHTARGET: opcode not yet implemented"),
}
} else if let xous::Message::MutableBorrow(m) = &envelope.body {
let lookup: &mut Lookup = unsafe { &mut *(m.buf.as_mut_ptr() as *mut Lookup) };
lookup.challenge[0] = lookup.challenge[0] + 1;
} else {
error!("BENCHTARGET: couldn't convert opcode");
}
}
}

View file

@ -0,0 +1,24 @@
[package]
name = "benchmark"
version = "0.1.0"
authors = ["bunnie <bunnie@kosagi.com>"]
edition = "2018"
description = "Benchmarks for Xous"
[dependencies]
xous = { path = "../../xous-rs" }
graphics-server = { path = "../graphics-server" }
ticktimer-server = { path = "../ticktimer-server" }
xous-names = { path = "../xous-names" }
log-server = { path = "../log-server" }
log = "0.4"
blitstr-ref = { path = "../../imports/blitstr-ref" }
benchmark-target = { path = "../benchmark-target" }
[target.'cfg(not(any(windows,unix)))'.dependencies]
utralib = { path = "../../utralib"}
[features]
debugprint = []
# default = ["debugprint"] # "debugprint"
default = []

View file

@ -0,0 +1,182 @@
#![cfg_attr(target_os = "none", no_std)]
#![cfg_attr(target_os = "none", no_main)]
use blitstr_ref as blitstr;
use blitstr::{Cursor, GlyphStyle};
use core::fmt::Write;
use graphics_server::{DrawStyle, PixelColor, Point, Rectangle};
use log::{error, info};
use xous::{String, Message, ScalarMessage};
use core::convert::TryFrom;
pub enum Opcode {
Start,
Stop,
}
impl core::convert::TryFrom<& Message> for Opcode {
type Error = &'static str;
fn try_from(message: & Message) -> Result<Self, Self::Error> {
match message {
Message::Scalar(m) => match m.id {
0 => Ok(Opcode::Start),
1 => Ok(Opcode::Stop),
_ => Err("BENCHMARK api: unknown Scalar ID"),
},
_ => Err("BENCHMARK api: unhandled message type"),
}
}
}
impl Into<Message> for Opcode {
fn into(self) -> Message {
match self {
Opcode::Start => Message::Scalar(ScalarMessage {
id: 0,
arg1: 0,
arg2: 0,
arg3: 0,
arg4: 0,
}),
Opcode::Stop => Message::Scalar(ScalarMessage {
id: 1,
arg1: 0,
arg2: 0,
arg3: 0,
arg4: 0,
}),
}
}
}
fn stopwatch_thread(_arg: xous::SID) {
info!("BENCHMARK|stopwatch: starting");
let ticktimer_server_id = xous::SID::from_bytes(b"ticktimer-server").unwrap();
let ticktimer_conn = xous::connect(ticktimer_server_id).unwrap();
let shell_conn = xous_names::request_connection_blocking(xous::names::SERVER_NAME_SHELL).expect("BENCHMARK|stopwatch: can't connect to main program");
let mut last_time: u64 = ticktimer_server::elapsed_ms(ticktimer_conn).unwrap();
let mut start_sent = false;
loop {
if let Ok(elapsed_time) = ticktimer_server::elapsed_ms(ticktimer_conn) {
if elapsed_time - last_time > 500 && !start_sent {
last_time = elapsed_time;
xous::send_message(shell_conn, Opcode::Start.into()).expect("BENCHMARK|stopwatch: couldn't send Start message");
start_sent = true;
} else if elapsed_time - last_time > 10_000 && start_sent {
last_time = elapsed_time;
start_sent = false;
xous::send_message(shell_conn, Opcode::Stop.into()).expect("BENCHMARK|stopwatch: couldn't send Stop message");
}
} else {
error!("error requesting ticktimer!")
}
if false {
// send a start loop message
xous::send_message(shell_conn, Opcode::Start.into()).expect("BENCHMARK|stopwatch: couldn't send Start message");
ticktimer_server::sleep_ms(ticktimer_conn, 10_000).expect("couldn't sleep");
// send a stop loop message
xous::send_message(shell_conn, Opcode::Stop.into()).expect("BENCHMARK|stopwatch: couldn't send Stop message");
// give a moment for the result to update
ticktimer_server::sleep_ms(ticktimer_conn, 500).expect("couldn't sleep");
}
xous::yield_slice();
}
}
#[xous::xous_main]
fn shell_main() -> ! {
log_server::init_wait().unwrap();
info!("BENCHMARK: ticktimer");
let ticktimer_server_id = xous::SID::from_bytes(b"ticktimer-server").unwrap();
let ticktimer_conn = xous::connect(ticktimer_server_id).unwrap();
let shell_server = xous_names::register_name(xous::names::SERVER_NAME_SHELL).expect("BENCHMARK: can't register server");
let graphics_conn = xous_names::request_connection_blocking(xous::names::SERVER_NAME_GFX).expect("BENCHMARK: can't connect to COM");
let target_conn = xous_names::request_connection_blocking(xous::names::SERVER_NAME_BENCHMARK).expect("BENCHMARK: can't connect to COM");
xous::create_thread_simple(stopwatch_thread, shell_server).unwrap();
info!("BENCHMARK: stopwatch thread started");
let screensize = graphics_server::screen_size(graphics_conn).expect("Couldn't get screen size");
let mut string_buffer = String::new(4096);
graphics_server::set_glyph_style(graphics_conn, GlyphStyle::Small)
.expect("unable to set glyph");
let (_, font_h) = graphics_server::query_glyph(graphics_conn).expect("unable to query glyph");
let status_clipregion =
Rectangle::new_coords_with_style(4, 0, screensize.x, font_h as i16 * 4, DrawStyle::new(PixelColor::Light, PixelColor::Light, 1));
graphics_server::draw_rectangle(graphics_conn, status_clipregion)
.expect("unable to clear region");
string_buffer.clear();
write!(&mut string_buffer, "First pass, please wait...");
let status_cursor = Cursor::from_top_left_of(status_clipregion.into());
graphics_server::set_cursor(graphics_conn, status_cursor).expect("can't set cursor");
graphics_server::draw_string(graphics_conn, &string_buffer).expect("unable to draw string");
graphics_server::flush(graphics_conn).expect("unable to draw to screen");
let mut start_time: u64 = 0;
let mut stop_time: u64 = 0;
let mut update_result: bool = false;
let mut count: u32 = 0;
let mut check_count: u32 = 0;
loop {
let maybe_env = xous::try_receive_message(shell_server).unwrap();
match maybe_env {
Some(envelope) => {
info!("BENCHMARK: Message: {:?}", envelope);
if let Ok(opcode) = Opcode::try_from(&envelope.body) {
match opcode {
Opcode::Start => {
start_time = ticktimer_server::elapsed_ms(ticktimer_conn).unwrap();
},
Opcode::Stop => {
stop_time = ticktimer_server::elapsed_ms(ticktimer_conn).unwrap();
update_result = true;
},
}
} else {
error!("BENCHMARK: couldn't convert opcode");
}
}
None => (), // don't yield, we are trying to run the loop as fast as we can...
}
// actual benchmark
// get a scalar message
if false {
// measured at 1349 iterations per second in this loop
count = benchmark_target::test_scalar(target_conn, count).expect("BENCHMARK: couldn't send test message");
check_count = check_count + 1;
} else {
count = benchmark_target::test_memory(target_conn, count).expect("BENCHMARK: couldn't send test message");
check_count = check_count + 1;
}
if update_result {
update_result = false;
graphics_server::draw_rectangle(graphics_conn, status_clipregion)
.expect("unable to clear region");
string_buffer.clear();
write!(&mut string_buffer, "Elapsed: {}, count: {}, check: {}",
stop_time - start_time, count, check_count).unwrap();
let status_cursor = Cursor::from_top_left_of(status_clipregion.into());
graphics_server::set_cursor(graphics_conn, status_cursor).expect("can't set cursor");
graphics_server::draw_string(graphics_conn, &string_buffer).expect("unable to draw string");
graphics_server::flush(graphics_conn).expect("unable to draw to screen");
count = 0;
check_count = 0;
}
}
}

View file

@ -8,12 +8,14 @@ for the core set of kernel services.
pub const SERVER_NAME_COM: &str = "_COM manager_";
pub const SERVER_NAME_SHELL: &str = "_Shell_";
pub const SERVER_NAME_GFX: &str = "_Graphics_";
pub const SERVER_NAME_FCCAGENT: &str = "_Agent for EMC Testing_";
pub const SERVER_NAME_KBD: &str = "_Matrix keyboard driver_";
pub const SERVER_NAME_TRNG: &str = "_TRNG manager_";
pub const SERVER_NAME_GAM: &str = "_Graphical Abstraction Manager_";
pub const SERVER_NAME_STATUS: &str = "_Status bar manager_";
pub const SERVER_NAME_FCCAGENT: &str = "_Agent for EMC Testing_";
pub const SERVER_NAME_BENCHMARK: &str= "_Benchmark target_";
/*
Global message IDs

View file

@ -79,8 +79,10 @@ fn build_hw_image(debug: bool, svd: Option<String>) -> Result<(), DynError> {
let kernel = build_kernel(debug)?;
let mut init = vec![];
for pkg in &[
"shell",
//"shell",
//"gam",
"benchmark",
"benchmark-target",
"graphics-server",
"ticktimer-server",
"log-server",