Add redux_regex test.

# Conflicts:
#	benches/wasm-kernel/Cargo.toml
This commit is contained in:
Sergey Pepyakin 2018-06-18 18:09:54 +03:00
parent ed4645b23a
commit c31498b8cc
5 changed files with 110 additions and 10 deletions

View File

@ -6,3 +6,4 @@ authors = ["Sergey Pepyakin <s.pepyakin@gmail.com>"]
[dependencies]
wasmi = { path = ".." }
assert_matches = "1.2"
wabt = "0.3"

View File

@ -4,6 +4,7 @@ extern crate test;
extern crate wasmi;
#[macro_use]
extern crate assert_matches;
extern crate wabt;
use std::error;
use std::fs::File;
@ -95,11 +96,55 @@ fn bench_rev_comp(b: &mut Bencher) {
"",
);
let result = memory
.get(output_data_mem_offset, REVCOMP_INPUT.len())
.get(output_data_mem_offset, REVCOMP_OUTPUT.len())
.expect("can't get result data from a wasm memory");
assert_eq!(&*result, REVCOMP_OUTPUT);
}
#[bench]
fn bench_regex_redux(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();
// Allocate buffers for the input and output.
let test_data_ptr: RuntimeValue = {
let input_size = RuntimeValue::I32(REVCOMP_INPUT.len() as i32);
assert_matches!(
instance.invoke_export("prepare_regex_redux", &[input_size], &mut NopExternals),
Ok(Some(v @ RuntimeValue::I32(_))) => v,
"",
)
};
// Get the pointer to the input buffer.
let input_data_mem_offset = assert_matches!(
instance.invoke_export("regex_redux_input_ptr", &[test_data_ptr], &mut NopExternals),
Ok(Some(RuntimeValue::I32(v))) => v as u32,
"",
);
// Copy test data inside the wasm memory.
let memory = instance.export_by_name("memory")
.expect("Expected export with a name 'memory'")
.as_memory()
.expect("'memory' should be a memory instance")
.clone();
memory
.set(input_data_mem_offset, REVCOMP_INPUT)
.expect("can't load test data into a wasm memory");
b.iter(|| {
instance
.invoke_export("bench_regex_redux", &[test_data_ptr], &mut NopExternals)
.unwrap();
});
}
#[bench]
fn fac_recursive(b: &mut Bencher) {
let wasm = wabt::wat2wasm(
@ -193,7 +238,7 @@ fn recursive_ok(b: &mut Bencher) {
b.iter(|| {
let value = instance
.invoke_export("call", &[RuntimeValue::I32(9999)], &mut NopExternals);
.invoke_export("call", &[RuntimeValue::I32(8000)], &mut NopExternals);
assert_matches!(value, Ok(Some(RuntimeValue::I32(0))));
});
}

View File

@ -8,7 +8,8 @@ crate-type = ["cdylib"]
[dependencies]
tiny-keccak = "1.4.2"
rlibc = "1.0"
regex = "0.2.10"
lazy_static = "1.0"
[profile.release]
panic = "abort"

View File

@ -1,14 +1,12 @@
#![no_std]
#![feature(lang_items)]
#![feature(core_intrinsics)]
#![feature(panic_implementation)]
extern crate rlibc;
extern crate tiny_keccak;
extern crate regex;
#[macro_use]
extern crate lazy_static;
use tiny_keccak::Keccak;
mod rev_complement;
mod regex_redux;
pub struct TinyKeccakTestData {
data: &'static [u8],
@ -74,7 +72,7 @@ pub extern "C" fn rev_complement_input_ptr(test_data: *mut RevComplementTestData
#[no_mangle]
pub extern "C" fn rev_complement_output_ptr(test_data: *mut RevComplementTestData) -> *const u8 {
unsafe {
(*test_data).output.as_mut_ptr()
(*test_data).output.as_ptr()
}
}
@ -85,3 +83,40 @@ pub extern "C" fn bench_rev_complement(test_data: *mut RevComplementTestData) {
(*test_data).output.copy_from_slice(&result);
}
}
pub struct RegexReduxTestData {
input: Box<[u8]>,
output: Option<usize>,
}
#[no_mangle]
pub extern "C" fn prepare_regex_redux(size: usize) -> *mut RegexReduxTestData {
regex_redux::prepare();
let input = vec![0; size];
let test_data = Box::new(
RegexReduxTestData {
input: input.into_boxed_slice(),
output: None,
}
);
// Basically leak the pointer to the test data. This shouldn't be harmful since `prepare` is called
// only once per bench run (not for the iteration), and afterwards whole memory instance is discarded.
Box::into_raw(test_data)
}
#[no_mangle]
pub extern "C" fn regex_redux_input_ptr(test_data: *mut RegexReduxTestData) -> *mut u8 {
unsafe {
(*test_data).input.as_mut_ptr()
}
}
#[no_mangle]
pub extern "C" fn bench_regex_redux(test_data: *mut RegexReduxTestData) {
unsafe {
let result = regex_redux::run(&*(*test_data).input);
(*test_data).output = Some(result);
}
}

View File

@ -0,0 +1,18 @@
//! Initially it supposed to be like [1]. However it turned out
//! that executing this code in wasmi way too slow.
//!
//! [1]: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/regexredux-rust-2.html
lazy_static! {
static ref REGEX: ::regex::bytes::Regex = {
::regex::bytes::Regex::new("agggtaa[cgt]|[acg]ttaccct").unwrap()
};
}
pub fn prepare() {
&REGEX;
}
pub fn run(seq: &[u8]) -> usize {
REGEX.find_iter(seq).count()
}