From 08c91f0998e42a67d27e5fe140f1211e3d1f5053 Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Wed, 23 May 2018 17:26:53 +0300 Subject: [PATCH] Add first bench --- Cargo.toml | 2 +- benches/.gitignore | 1 + benches/Cargo.toml | 7 +++++ benches/build.rs | 32 ++++++++++++++++++++ benches/src/lib.rs | 44 +++++++++++++++++++++++++++ benches/wasm-kernel/.gitignore | 1 + benches/wasm-kernel/Cargo.toml | 16 ++++++++++ benches/wasm-kernel/src/lib.rs | 54 ++++++++++++++++++++++++++++++++++ 8 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 benches/.gitignore create mode 100644 benches/Cargo.toml create mode 100644 benches/build.rs create mode 100644 benches/src/lib.rs create mode 100644 benches/wasm-kernel/.gitignore create mode 100644 benches/wasm-kernel/Cargo.toml create mode 100644 benches/wasm-kernel/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 6014301..b74d752 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ repository = "https://github.com/paritytech/wasmi" documentation = "https://paritytech.github.io/wasmi/" description = "WebAssembly interpreter" keywords = ["wasm", "webassembly", "bytecode", "interpreter"] -exclude = [ "/res/*", "/tests/*", "/fuzz/*" ] +exclude = [ "/res/*", "/tests/*", "/fuzz/*", "/benches/*" ] [dependencies] parity-wasm = "0.27" diff --git a/benches/.gitignore b/benches/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/benches/.gitignore @@ -0,0 +1 @@ +/target diff --git a/benches/Cargo.toml b/benches/Cargo.toml new file mode 100644 index 0000000..69e0271 --- /dev/null +++ b/benches/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "benches" +version = "0.1.0" +authors = ["Sergey Pepyakin "] + +[dependencies] +wasmi = { path = ".." } diff --git a/benches/build.rs b/benches/build.rs new file mode 100644 index 0000000..9cb9ac1 --- /dev/null +++ b/benches/build.rs @@ -0,0 +1,32 @@ +use std::env; +use std::process; + + +fn main() { + println!("cargo:rerun-if-changed=./wasm-kernel/"); + + // The CARGO environment variable provides a path to the executable that + // runs this build process. + let cargo_bin = env::var("CARGO").expect("CARGO env variable should be defined"); + + // Build a release version of wasm-kernel. The code in the output wasm binary + // will be used in benchmarks. + let output = process::Command::new(cargo_bin) + .arg("build") + .arg("--target=wasm32-unknown-unknown") + .arg("--release") + .arg("--manifest-path=./wasm-kernel/Cargo.toml") + .arg("--verbose") + .output() + .expect("failed to execute `cargo`"); + + if !output.status.success() { + let msg = format!( + "status: {status}\nstdout: {stdout}\nstderr: {stderr}\n", + status=output.status, + stdout=String::from_utf8_lossy(&output.stdout), + stderr=String::from_utf8_lossy(&output.stderr), + ); + panic!("{}", msg); + } +} diff --git a/benches/src/lib.rs b/benches/src/lib.rs new file mode 100644 index 0000000..21fc831 --- /dev/null +++ b/benches/src/lib.rs @@ -0,0 +1,44 @@ +#![feature(test)] + +extern crate test; +extern crate wasmi; + +use std::error; +use std::fs::File; +use wasmi::{ImportsBuilder, Module, ModuleInstance, NopExternals, RuntimeValue}; + +use test::Bencher; + +// Load a module from a file. +fn load_from_file(filename: &str) -> Result> { + use std::io::prelude::*; + let mut file = File::open(filename)?; + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + Ok(Module::from_buffer(buf)?) +} + +#[bench] +fn bench_tiny_keccak(b: &mut Bencher) { + let wasm_kernel = load_from_file( + "./wasm-kernel/target/wasm32-unknown-unknown/release/wasm_kernel.wasm", + ).expect("failed to load wasm_kernel. Is `build.rs` broken?"); + + let instance = ModuleInstance::new(&wasm_kernel, &ImportsBuilder::default()) + .expect("failed to instantiate wasm module") + .assert_no_start(); + + let test_data = match instance + .invoke_export("prepare_tiny_keccak", &[], &mut NopExternals) + .unwrap() + { + Some(v @ RuntimeValue::I32(_)) => v, + _ => panic!(), + }; + + b.iter(|| { + instance + .invoke_export("bench_tiny_keccak", &[test_data], &mut NopExternals) + .unwrap(); + }); +} diff --git a/benches/wasm-kernel/.gitignore b/benches/wasm-kernel/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/benches/wasm-kernel/.gitignore @@ -0,0 +1 @@ +/target diff --git a/benches/wasm-kernel/Cargo.toml b/benches/wasm-kernel/Cargo.toml new file mode 100644 index 0000000..f9717f5 --- /dev/null +++ b/benches/wasm-kernel/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "wasm-kernel" +version = "0.1.0" +authors = ["Sergey Pepyakin "] + +[lib] +crate-type = ["cdylib"] + +[dependencies] +tiny-keccak = "1.4.2" +rlibc = "1.0" + +[profile.release] +panic = "abort" +lto = true +opt-level = "z" diff --git a/benches/wasm-kernel/src/lib.rs b/benches/wasm-kernel/src/lib.rs new file mode 100644 index 0000000..7f2f154 --- /dev/null +++ b/benches/wasm-kernel/src/lib.rs @@ -0,0 +1,54 @@ +#![no_std] +#![feature(lang_items)] +#![feature(core_intrinsics)] + +extern crate rlibc; +extern crate tiny_keccak; + +use tiny_keccak::Keccak; + +#[no_mangle] +#[lang = "panic_fmt"] +pub extern "C" fn panic_fmt( + _args: ::core::fmt::Arguments, + _file: &'static str, + _line: u32, + _col: u32, +) -> ! { + use core::intrinsics; + unsafe { + intrinsics::abort(); + } +} + +pub struct TinyKeccakTestData { + data: &'static [u8], + result: &'static mut [u8], +} + +#[no_mangle] +pub extern "C" fn prepare_tiny_keccak() -> *const TinyKeccakTestData { + static DATA: [u8; 4096] = [254u8; 4096]; + static mut RESULT: [u8; 32] = [0u8; 32]; + + static mut TEST_DATA: Option = None; + + unsafe { + if let None = TEST_DATA { + TEST_DATA = Some(TinyKeccakTestData { + data: &DATA, + result: &mut RESULT, + }); + } + TEST_DATA.as_ref().unwrap() as *const TinyKeccakTestData + } +} + +#[no_mangle] +pub extern "C" fn bench_tiny_keccak(test_data: *const TinyKeccakTestData) { + unsafe { + let mut keccak = Keccak::new_sha3_256(); + keccak.update((*test_data).data); + keccak.finalize((*test_data).result); + } +}