You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
3.2 KiB
89 lines
3.2 KiB
//! Measure some common WASI call scenarios.
|
|
|
|
use criterion::{criterion_group, criterion_main, Criterion};
|
|
use std::{fs::File, path::Path, time::Instant};
|
|
use wasi_common::{sync::WasiCtxBuilder, WasiCtx};
|
|
use wasmtime::{Engine, Linker, Module, Store, TypedFunc};
|
|
|
|
criterion_group!(benches, bench_wasi);
|
|
criterion_main!(benches);
|
|
|
|
fn bench_wasi(c: &mut Criterion) {
|
|
let _ = env_logger::try_init();
|
|
|
|
// Build a zero-filled test file if it does not yet exist.
|
|
let test_file = Path::new("benches/wasi/test.bin");
|
|
if !test_file.is_file() {
|
|
let file = File::create(test_file).unwrap();
|
|
file.set_len(4096).unwrap();
|
|
}
|
|
|
|
// Benchmark each `*.wat` file in the `wasi` directory.
|
|
for file in std::fs::read_dir("benches/wasi").unwrap() {
|
|
let path = file.unwrap().path();
|
|
if path.extension().map(|e| e == "wat").unwrap_or(false) {
|
|
let wat = std::fs::read(&path).unwrap();
|
|
let (mut store, run_fn) = instantiate(&wat);
|
|
let bench_name = format!("wasi/{}", path.file_name().unwrap().to_string_lossy());
|
|
// To avoid overhead, the module itself must iterate the expected
|
|
// number of times in a specially-crafted `run` function (see
|
|
// `instantiate` for details).
|
|
c.bench_function(&bench_name, move |b| {
|
|
b.iter_custom(|iters| {
|
|
let start = Instant::now();
|
|
let result = run_fn.call(&mut store, iters).unwrap();
|
|
assert_eq!(iters, result);
|
|
start.elapsed()
|
|
})
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Compile and instantiate the Wasm module, returning the exported `run`
|
|
/// function. This function expects `run` to:
|
|
/// - have a single `u64` parameter indicating the number of loop iterations to
|
|
/// execute
|
|
/// - execute the body of the function for that number of loop iterations
|
|
/// - return a single `u64` indicating how many loop iterations were executed
|
|
/// (to double-check)
|
|
fn instantiate(wat: &[u8]) -> (Store<WasiCtx>, TypedFunc<u64, u64>) {
|
|
let engine = Engine::default();
|
|
let wasi = wasi_context();
|
|
let mut store = Store::new(&engine, wasi);
|
|
let module = Module::new(&engine, wat).unwrap();
|
|
let mut linker = Linker::new(&engine);
|
|
wasi_common::sync::add_to_linker(&mut linker, |cx| cx).unwrap();
|
|
let instance = linker.instantiate(&mut store, &module).unwrap();
|
|
let run = instance.get_typed_func(&mut store, "run").unwrap();
|
|
(store, run)
|
|
}
|
|
|
|
/// Build a WASI context with some actual data to retrieve.
|
|
fn wasi_context() -> WasiCtx {
|
|
WasiCtxBuilder::new()
|
|
.envs(&[
|
|
("a".to_string(), "b".to_string()),
|
|
("b".to_string(), "c".to_string()),
|
|
("c".to_string(), "d".to_string()),
|
|
])
|
|
.unwrap()
|
|
.args(&[
|
|
"exe".to_string(),
|
|
"--flag1".to_string(),
|
|
"--flag2".to_string(),
|
|
"--flag3".to_string(),
|
|
"--flag4".to_string(),
|
|
])
|
|
.unwrap()
|
|
.preopened_dir(
|
|
wasi_common::sync::Dir::open_ambient_dir(
|
|
"benches/wasi",
|
|
wasi_common::sync::ambient_authority(),
|
|
)
|
|
.unwrap(),
|
|
"/",
|
|
)
|
|
.unwrap()
|
|
.build()
|
|
}
|
|
|