Skip to content

Commit

Permalink
Use Pulley for Wasmtime in wasm-bench (#753)
Browse files Browse the repository at this point in the history
  • Loading branch information
ia0 authored Feb 18, 2025
1 parent bf09069 commit cddad99
Show file tree
Hide file tree
Showing 9 changed files with 724 additions and 187 deletions.
782 changes: 625 additions & 157 deletions crates/wasm-bench/Cargo.lock

Large diffs are not rendered by default.

15 changes: 10 additions & 5 deletions crates/wasm-bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,31 @@ features = ["build-bindgen", "use-32bit-slots"]
optional = true

[dependencies.wasmtime]
version = "28.0.0"
git = "https://github.com/bytecodealliance/wasmtime.git"
default-features = false
features = ["cranelift", "runtime"]
features = ["runtime"]
optional = true

[build-dependencies.wasmtime]
git = "https://github.com/bytecodealliance/wasmtime.git"
features = ["pulley"]

[features]
_target-embedded = ["dep:embedded-alloc", "wasmtime?/pulley"]
runtime-base = ["dep:wasefire-interpreter"]
runtime-wasm3 = ["dep:wasm3"]
runtime-wasmi = ["dep:wasmi"]
runtime-wasmtime = ["dep:wasmtime"]
target-linux = []
target-linux = ["wasmtime?/cranelift"]
target-nordic = [
"_target-embedded",
"dep:cortex-m",
"dep:cortex-m-rt",
"dep:embedded-alloc",
"dep:nrf52840-hal",
"dep:panic-rtt-target",
"dep:rtt-target",
]
target-riscv = ["dep:embedded-alloc", "dep:portable-atomic", "dep:riscv", "dep:riscv-rt"]
target-riscv = ["_target-embedded", "dep:portable-atomic", "dep:riscv", "dep:riscv-rt"]

[profile.release]
codegen-units = 1
Expand Down
64 changes: 59 additions & 5 deletions crates/wasm-bench/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,70 @@ use std::io::Write;
use std::path::PathBuf;

fn main() {
let memory = if std::env::var_os("CARGO_FEATURE_TARGET_NORDIC").is_some() {
Some(include_bytes!("memory-nordic.x").as_slice())
let out = PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
let target = if std::env::var_os("CARGO_FEATURE_TARGET_LINUX").is_some() {
Target::Linux
} else if std::env::var_os("CARGO_FEATURE_TARGET_NORDIC").is_some() {
Target::Nordic
} else if std::env::var_os("CARGO_FEATURE_TARGET_RISCV").is_some() {
Some(include_bytes!("memory-riscv.x").as_slice())
Target::Riscv
} else {
None
panic!("one of target-{{linux,nordic,riscv}} must be enabled")
};
let runtime = if std::env::var_os("CARGO_FEATURE_RUNTIME_BASE").is_some() {
Runtime::Base
} else if std::env::var_os("CARGO_FEATURE_RUNTIME_WASM3").is_some() {
Runtime::Wasm3
} else if std::env::var_os("CARGO_FEATURE_RUNTIME_WASMI").is_some() {
Runtime::Wasmi
} else if std::env::var_os("CARGO_FEATURE_RUNTIME_WASMTIME").is_some() {
Runtime::Wasmtime
} else {
panic!("one of runtime-{{base,wasm3,wasmi,wasmtime}} must be enabled")
};
let memory = match target {
Target::Linux => None,
Target::Nordic => Some(include_bytes!("memory-nordic.x").as_slice()),
Target::Riscv => Some(include_bytes!("memory-riscv.x").as_slice()),
};
if let Some(memory) = memory {
let out = PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
println!("cargo:rustc-link-search={}", out.display());
File::create(out.join("memory.x")).unwrap().write_all(memory).unwrap();
}
let module = if runtime == Runtime::Wasmtime && target.is_embedded() {
let mut config = wasmtime::Config::new();
config.target("pulley32").unwrap();
let engine = wasmtime::Engine::new(&config).unwrap();
&engine.precompile_module(WASM).unwrap()
} else {
WASM
};
std::fs::write(out.join("module.bin"), module).unwrap();
}

const WASM: &[u8] = include_bytes!("../../third_party/wasm3/wasm-coremark/coremark-minimal.wasm");

#[derive(Clone, Copy, PartialEq, Eq)]
enum Target {
Linux,
Nordic,
Riscv,
}

#[derive(Clone, Copy, PartialEq, Eq)]
enum Runtime {
Base,
Wasm3,
Wasmi,
Wasmtime,
}

impl Target {
fn is_embedded(self) -> bool {
match self {
Target::Linux => false,
Target::Nordic => true,
Target::Riscv => true,
}
}
}
6 changes: 4 additions & 2 deletions crates/wasm-bench/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ esac

# See test.sh for supported (and tested) combinations.
case $1-$2 in
*-base|nordic-wasmi) ;;
*-base|linux-*|nordic-wasmi|nordic-wasmtime) ;;
*) e "Unsupported combination: $1 $2" ;;
esac

FEATURES=--features=target-$1,runtime-$2
shift 2
set -- --release $TARGET $FEATURES "$@"

x cargo run --release $TARGET $FEATURES "$@"
[ -z "$TARGET" ] || x ../../scripts/wrapper.sh cargo-size "$@"
x cargo run "$@"
11 changes: 5 additions & 6 deletions crates/wasm-bench/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
// limitations under the License.

#![no_std]
#![cfg_attr(any(feature = "target-nordic", feature = "target-riscv"), no_main)]
#![cfg_attr(feature = "_target-embedded", no_main)]

extern crate alloc;
#[cfg(feature = "target-linux")]
#[cfg(not(feature = "_target-embedded"))]
extern crate std;

#[cfg(any(feature = "target-nordic", feature = "target-riscv"))]
#[cfg(feature = "_target-embedded")]
mod allocator;
#[cfg_attr(feature = "runtime-base", path = "runtime/base.rs")]
#[cfg_attr(feature = "runtime-wasm3", path = "runtime/wasm3.rs")]
Expand All @@ -31,13 +31,12 @@ mod runtime;
#[cfg_attr(feature = "target-riscv", path = "target/riscv.rs")]
mod target;

const WASM: &[u8] =
include_bytes!("../../../third_party/wasm3/wasm-coremark/coremark-minimal.wasm");
const MODULE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/module.bin"));

fn main() {
println!("Running CoreMark measurement...");
let start = target::clock_ms();
let result = runtime::run(WASM);
let result = runtime::run(MODULE);
let duration = target::clock_ms() - start;
println!("CoreMark result: {} (in {}s)", result, duration as f32 / 1000.);
}
Expand Down
4 changes: 0 additions & 4 deletions crates/wasm-bench/src/runtime/wasmi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,12 @@ use wasmi::*;
pub(crate) fn run(wasm: &[u8]) -> f32 {
let engine = Engine::default();
let module = Module::new(&engine, wasm).unwrap();

let mut store = Store::new(&engine, ());
let mut linker = Linker::<()>::new(&engine);

let clock_ms =
Func::wrap(&mut store, move |_: Caller<'_, ()>| -> u64 { crate::target::clock_ms() });
linker.define("env", "clock_ms", clock_ms).unwrap();

let instance = linker.instantiate(&mut store, &module).unwrap().start(&mut store).unwrap();

let func = instance.get_typed_func::<(), f32>(&store, "run").unwrap();
func.call(&mut store, ()).unwrap()
}
22 changes: 18 additions & 4 deletions crates/wasm-bench/src/runtime/wasmtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,31 @@ use wasmtime::*;

pub(crate) fn run(wasm: &[u8]) -> f32 {
let engine = Engine::default();
#[cfg(feature = "_target-embedded")]
let module = unsafe { Module::deserialize(&engine, wasm) }.unwrap();
#[cfg(not(feature = "_target-embedded"))]
let module = Module::new(&engine, wasm).unwrap();

let mut store = Store::new(&engine, ());
let mut linker = Linker::new(&engine);

let clock_ms =
Func::wrap(&mut store, move |_: Caller<'_, ()>| -> u64 { crate::target::clock_ms() });
linker.define(&mut store, "env", "clock_ms", clock_ms).unwrap();

let instance = linker.instantiate(&mut store, &module).unwrap();

let func = instance.get_typed_func::<(), f32>(&mut store, "run").unwrap();
func.call(&mut store, ()).unwrap()
}

#[cfg(feature = "_target-embedded")]
mod emdedded {
#[unsafe(no_mangle)]
extern "C" fn wasmtime_tls_get() -> *mut u8 {
unsafe { TLS_PTR }
}

#[unsafe(no_mangle)]
extern "C" fn wasmtime_tls_set(ptr: *mut u8) {
unsafe { TLS_PTR = ptr }
}

static mut TLS_PTR: *mut u8 = core::ptr::null_mut();
}
5 changes: 2 additions & 3 deletions crates/wasm-bench/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ cargo check --bin=wasm-bench --target=thumbv7em-none-eabi --features=target-nord
# wasm3/source/wasm3.h:16:10: fatal error: 'stdlib.h' file not found
# cargo check --bin=wasm-bench --target=thumbv7em-none-eabi --features=target-nordic,runtime-wasm3
cargo check --bin=wasm-bench --target=thumbv7em-none-eabi --features=target-nordic,runtime-wasmi
# error in crate arbitrary: can't find crate for `std`
# cargo check --bin=wasm-bench --target=thumbv7em-none-eabi --features=target-nordic,runtime-wasmtime
cargo check --bin=wasm-bench --target=thumbv7em-none-eabi --features=target-nordic,runtime-wasmtime

cargo check --bin=wasm-bench --target=riscv32imc-unknown-none-elf \
--features=target-riscv,runtime-base
Expand All @@ -41,6 +40,6 @@ cargo check --bin=wasm-bench --target=riscv32imc-unknown-none-elf \
# error: no method named `compare_exchange` found for struct `AtomicUsize` in the current scope
# cargo check --bin=wasm-bench --target=riscv32imc-unknown-none-elf \
# --features=target-riscv,runtime-wasmi
# error in crate once_cell: can't find crate for `std`
# error: unresolved import `alloc::sync`
# cargo check --bin=wasm-bench --target=riscv32imc-unknown-none-elf \
# --features=target-riscv,runtime-wasmtime
2 changes: 1 addition & 1 deletion taplo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ reorder_keys = true

[[rule]]
formatting = { reorder_keys = false }
keys = ["dependencies.*", "package"]
keys = ["build-dependencies.*", "dependencies.*", "dev-dependencies.*", "package"]

[[rule]]
formatting = { reorder_keys = true }
Expand Down

0 comments on commit cddad99

Please # to comment.