Add a simple bench (#90)

* Add first bench

* Refactor travis.yml

* Use assert_matches!

* sha3_256 → keccak256
This commit is contained in:
Sergey Pepyakin 2018-05-24 16:31:15 +03:00 committed by GitHub
parent d926993c6c
commit 6cf0ebc79e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 164 additions and 12 deletions

View File

@ -3,6 +3,9 @@ sudo: required
language:
- rust
- cpp
rust:
- nightly
- stable
addons:
apt:
sources:
@ -12,18 +15,16 @@ addons:
- g++-6
- cmake
env:
- NIGHTLY_TOOLCHAIN=nightly-2018-02-05
- CC=/usr/bin/gcc-6 CXX=/usr/bin/g++-6
install:
# Install `cargo-deadlinks` unless it is currently installed.
- command -v cargo-deadlinks &> /dev/null || cargo install cargo-deadlinks
# Install nightly toolchain.
- rustup toolchain install $NIGHTLY_TOOLCHAIN
- if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then rustup target add wasm32-unknown-unknown; fi
script:
- export CC=/usr/bin/gcc-6
- export CXX=/usr/bin/g++-6
# Make sure fuzz targets are not broken.
- rustup run $NIGHTLY_TOOLCHAIN cargo check --tests --manifest-path=fuzz/Cargo.toml
- if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cargo check --tests --manifest-path=fuzz/Cargo.toml; fi
- if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cargo check --benches --manifest-path=benches/Cargo.toml; fi
- ./test.sh
- ./doc.sh
after_success: |

View File

@ -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"

1
benches/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

8
benches/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "benches"
version = "0.1.0"
authors = ["Sergey Pepyakin <s.pepyakin@gmail.com>"]
[dependencies]
wasmi = { path = ".." }
assert_matches = "1.2"

32
benches/build.rs Normal file
View File

@ -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);
}
}

43
benches/src/lib.rs Normal file
View File

@ -0,0 +1,43 @@
#![feature(test)]
extern crate test;
extern crate wasmi;
#[macro_use]
extern crate assert_matches;
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<Module, Box<error::Error>> {
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_ptr = assert_matches!(
instance.invoke_export("prepare_tiny_keccak", &[], &mut NopExternals),
Ok(Some(v @ RuntimeValue::I32(_))) => v
);
b.iter(|| {
instance
.invoke_export("bench_tiny_keccak", &[test_data_ptr], &mut NopExternals)
.unwrap();
});
}

1
benches/wasm-kernel/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

View File

@ -0,0 +1,16 @@
[package]
name = "wasm-kernel"
version = "0.1.0"
authors = ["Sergey Pepyakin <s.pepyakin@gmail.com>"]
[lib]
crate-type = ["cdylib"]
[dependencies]
tiny-keccak = "1.4.2"
rlibc = "1.0"
[profile.release]
panic = "abort"
lto = true
opt-level = "z"

View File

@ -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<TinyKeccakTestData> = 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_keccak256();
keccak.update((*test_data).data);
keccak.finalize((*test_data).result);
}
}

6
doc.sh
View File

@ -4,11 +4,7 @@ set -eux
cd $(dirname $0)
if [ -s NIGHTLY_TOOLCHAIN ]; then
rustup run $NIGHTLY_TOOLCHAIN cargo doc
else
cargo doc
fi;
cargo doc
# cargo-deadlinks will check any links in docs generated by `cargo doc`.
# This is useful as rustdoc uses raw links which are error prone.