Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add benchmark runner and nginx compile vs. load bench #201

Merged
merged 8 commits into from
Feb 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
271 changes: 219 additions & 52 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ You can also run integration tests with:
make integration-tests
```

## Benchmarking

Benchmarks can be run with:

```sh
cargo bench --all
```

## Roadmap

Wasmer is an open project guided by strong principles, aiming to be modular, flexible and fast. It is open to the community to help set its direction.
Expand Down
2 changes: 1 addition & 1 deletion lib/clif-backend/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use cranelift_wasm;
use hashbrown::HashMap;
use std::sync::Arc;

use wasmer_runtime_core::cache::{Artifact, Error as CacheError, WasmHash};
use wasmer_runtime_core::cache::{Artifact, Error as CacheError};

use wasmer_runtime_core::{
backend::Backend,
Expand Down
4 changes: 3 additions & 1 deletion lib/runtime-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ version = "1.0"
version = "0.10"
[dependencies.serde-bench]
version = "0.0.7"
[dependencies.sha2]
[dependencies.meowhash]
version = "0.1.2"
[dependencies.digest]
version = "0.8.0"
[dependencies.hashbrown]
version = "0.1"
Expand Down
30 changes: 19 additions & 11 deletions lib/runtime-core/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ use crate::{
module::{Module, ModuleInfo},
sys::Memory,
};
use sha2::{Digest, Sha256};
use std::{io, mem, slice};
use digest::Digest;
use meowhash::MeowHasher;
use std::{fmt, io, mem, slice};

#[derive(Debug)]
pub enum InvalidFileType {
Expand Down Expand Up @@ -33,7 +34,7 @@ impl From<io::Error> for Error {
///
/// [`Cache`]: trait.Cache.html
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct WasmHash([u8; 32]);
pub struct WasmHash([u8; 32], [u8; 32]);

impl WasmHash {
/// Hash a wasm module.
Expand All @@ -42,19 +43,26 @@ impl WasmHash {
/// This does no verification that the supplied data
/// is, in fact, a wasm module.
pub fn generate(wasm: &[u8]) -> Self {
let mut array = [0u8; 32];
array.copy_from_slice(Sha256::digest(wasm).as_slice());
WasmHash(array)
let mut first_part = [0u8; 32];
let mut second_part = [0u8; 32];
let generic_array = MeowHasher::digest(wasm);

first_part.copy_from_slice(&generic_array[0..32]);
second_part.copy_from_slice(&generic_array[32..64]);
WasmHash(first_part, second_part)
}

/// Create the hexadecimal representation of the
/// stored hash.
pub fn encode(self) -> String {
hex::encode(self.0)
hex::encode(&self.into_array() as &[u8])
}

pub(crate) fn into_array(self) -> [u8; 32] {
self.0
pub(crate) fn into_array(self) -> [u8; 64] {
let mut total = [0u8; 64];
total[0..32].copy_from_slice(&self.0);
total[32..64].copy_from_slice(&self.1);
total
}
}

Expand Down Expand Up @@ -189,8 +197,8 @@ impl Artifact {
///
/// The `wasmer-runtime` supplies a naive `FileSystemCache` api.
pub trait Cache {
type LoadError;
type StoreError;
type LoadError: fmt::Debug;
type StoreError: fmt::Debug;

fn load(&self, key: WasmHash) -> Result<Module, Self::LoadError>;
fn store(&mut self, key: WasmHash, module: Module) -> Result<(), Self::StoreError>;
Expand Down
2 changes: 1 addition & 1 deletion lib/runtime-core/src/module.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
backend::{Backend, FuncResolver, ProtectedCaller},
cache::{Artifact, Error as CacheError, WasmHash},
cache::{Artifact, Error as CacheError},
error,
import::ImportObject,
structures::{Map, TypedIndex},
Expand Down
8 changes: 8 additions & 0 deletions lib/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,13 @@ version = "0.1.2"
path = "../clif-backend"
version = "0.1.2"

[dev-dependencies]
tempfile = "3.0.7"
criterion = "0.2"

[features]
debug = ["wasmer-clif-backend/debug", "wasmer-runtime-core/debug"]

[[bench]]
name = "nginx"
harness = false
53 changes: 53 additions & 0 deletions lib/runtime/benches/nginx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#[macro_use]
extern crate criterion;
use criterion::Criterion;
use tempfile::tempdir;
use wasmer_runtime::{
cache::{Cache, FileSystemCache, WasmHash},
compile, validate,
};

static NGINX_WASM: &'static [u8] = include_bytes!("../../../examples/nginx/nginx.wasm");

fn compile_module() {
compile(NGINX_WASM).unwrap();
}

fn load_module(hash: WasmHash, cache: &impl Cache) {
cache.load(hash).expect("could not load module");
}

fn hashing_benchmark(c: &mut Criterion) {
c.bench_function("nginx HASH", |b| b.iter(|| WasmHash::generate(NGINX_WASM)));
}

fn validate_benchmark(c: &mut Criterion) {
c.bench_function("nginx validate", |b| b.iter(|| validate(NGINX_WASM)));
}

fn compile_benchmark(c: &mut Criterion) {
c.bench_function("nginx compile", |b| b.iter(|| compile_module()));
}

fn load_benchmark(c: &mut Criterion) {
c.bench_function("nginx load", |b| {
let tempdir = tempdir().unwrap();
let mut cache = unsafe {
FileSystemCache::new(tempdir.path()).expect("unable to create file system cache")
};
let module = compile(NGINX_WASM).unwrap();
let wasm_hash = WasmHash::generate(NGINX_WASM);
cache
.store(wasm_hash, module)
.expect("unable to store into cache");

b.iter(|| load_module(wasm_hash, &cache))
});
}

criterion_group! {
name = benches;
config = Criterion::default().sample_size(10);
targets = validate_benchmark, hashing_benchmark, compile_benchmark, load_benchmark
}
criterion_main!(benches);