From a31f6f16ade8c24a398c8140d9e8d3888ca5eaa2 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Wed, 11 Oct 2023 16:27:49 +0400 Subject: [PATCH] wip on fixing benchmarks --- crates/host/src/guest.rs | 3 ++ test/Cargo.toml | 2 +- test/benches/bench.rs | 92 +++++++++++++++++-------------------- test/src/wasms.rs | 11 ++++- test/wasm_empty/src/wasm.rs | 2 + 5 files changed, 57 insertions(+), 53 deletions(-) diff --git a/crates/host/src/guest.rs b/crates/host/src/guest.rs index 9c6e205b..a31ffa71 100644 --- a/crates/host/src/guest.rs +++ b/crates/host/src/guest.rs @@ -125,6 +125,9 @@ where /// Host calling guest for the function named `call` with the given `payload` in a vector of bytes /// result is either a vector of bytes from the guest found at the location of the returned guest /// allocation pointer or a `RuntimeError` built from a `WasmError`. +/// The reason that this takes a separate store and instance is that the host does not neccessarily +/// have access to an InstanceWithStore, such as the case when the guest is called from within a +/// host function call. pub fn call( store_mut: &mut StoreMut, instance: Arc, diff --git a/test/Cargo.toml b/test/Cargo.toml index 03e34b0a..6dc8aaf5 100644 --- a/test/Cargo.toml +++ b/test/Cargo.toml @@ -10,7 +10,7 @@ holochain_wasmer_host = { path = "../crates/host" } holochain_serialized_bytes = "=0.0.53" serde = "1" test_common = { path = "./common" } -criterion = "0.3" +criterion = { version = "0.3", features = ["html_reports"] } rand = "0.8" serde_bytes = "0.11" parking_lot = "0.12" diff --git a/test/benches/bench.rs b/test/benches/bench.rs index 224836b5..448bc374 100644 --- a/test/benches/bench.rs +++ b/test/benches/bench.rs @@ -3,8 +3,8 @@ use criterion::Throughput; use criterion::{criterion_group, criterion_main, Criterion}; use holochain_wasmer_host::prelude::*; use rand::prelude::*; -use std::sync::Arc; use test::wasms::TestWasm; +use wasmer::AsStoreMut; /// create a module pub fn wasm_module(c: &mut Criterion) { @@ -38,38 +38,7 @@ pub fn wasm_instance(c: &mut Criterion) { ] { group.bench_function(BenchmarkId::new("wasm_instance", wasm.name()), |b| { b.iter(|| { - let module = wasm.module(false); - let env = Env::default(); - let import_object: wasmer::ImportObject = imports! { - "env" => { - "__hc__short_circuit_5" => Function::new_native_with_env( - module.store(), - env.clone(), - test::short_circuit - ), - "__hc__test_process_string_2" => Function::new_native_with_env( - module.store(), - env.clone(), - test::test_process_string - ), - "__hc__test_process_struct_2" => Function::new_native_with_env( - module.store(), - env.clone(), - test::test_process_struct - ), - "__hc__debug_1" => Function::new_native_with_env( - module.store(), - env.clone(), - test::debug - ), - "__hc__pages_1" => Function::new_native_with_env( - module.store(), - env.clone(), - test::pages - ), - }, - }; - let _ = wasmer::Instance::new(&module, &import_object).unwrap(); + wasm.unmetered_instance(); }); }); } @@ -81,7 +50,7 @@ pub fn wasm_instance(c: &mut Criterion) { pub fn wasm_call(c: &mut Criterion) { let mut group = c.benchmark_group("wasm_call"); - let instance = TestWasm::Io.unmetered_instance(); + let instance_with_store = TestWasm::Io.unmetered_instance(); macro_rules! bench_call { ( $fs:expr; $t:tt; $n:ident; $build:expr; ) => { @@ -100,8 +69,12 @@ pub fn wasm_call(c: &mut Criterion) { &$n, |b, _| { b.iter(|| { + let instance = instance_with_store.instance.clone(); + let mut store_lock = instance_with_store.store.lock(); + let mut store_mut = store_lock.as_store_mut(); let _drop: test_common::$t = holochain_wasmer_host::guest::call( - Arc::clone(&instance), + &mut store_mut, + instance, f, &input, ) @@ -143,7 +116,7 @@ pub fn wasm_call(c: &mut Criterion) { pub fn wasm_call_n(c: &mut Criterion) { let mut group = c.benchmark_group("wasm_call_n"); - let instance = TestWasm::Io.instance(); + let instance_with_store = TestWasm::Io.instance(); macro_rules! bench_n { ( $fs:expr; $t:ty; ) => { @@ -161,12 +134,19 @@ pub fn wasm_call_n(c: &mut Criterion) { &n, |b, _| { b.iter(|| { - let _: $t = holochain_wasmer_host::guest::call( - Arc::clone(&instance), - f, - test_common::IntegerType::from(n), - ) - .expect("failed deserialize"); + let instance = instance_with_store.instance.clone(); + let store = instance_with_store.store.clone(); + { + let mut store_lock = store.lock(); + let mut store_mut = store_lock.as_store_mut(); + let _: $t = holochain_wasmer_host::guest::call( + &mut store_mut, + instance, + f, + test_common::IntegerType::from(n), + ) + .expect("failed deserialize"); + } }); }, ); @@ -185,7 +165,7 @@ pub fn wasm_call_n(c: &mut Criterion) { pub fn test_process_string(c: &mut Criterion) { let mut group = c.benchmark_group("test_process_string"); - let instance = TestWasm::Test.instance(); + let instance_with_store = TestWasm::Test.instance(); for n in vec![0, 1, 1_000, 1_000_000] { group.throughput(Throughput::Bytes(n)); @@ -193,12 +173,19 @@ pub fn test_process_string(c: &mut Criterion) { let input = test_common::StringType::from(".".repeat(n.try_into().unwrap())); group.bench_with_input(BenchmarkId::new("test_process_string", n), &n, |b, _| { b.iter(|| { - let _: test_common::StringType = holochain_wasmer_host::guest::call( - Arc::clone(&instance), - "process_string", - &input, - ) - .unwrap(); + let instance = instance_with_store.instance.clone(); + let store = instance_with_store.store.clone(); + { + let mut store_lock = store.lock(); + let mut store_mut = store_lock.as_store_mut(); + let _drop: test_common::StringType = holochain_wasmer_host::guest::call( + &mut store_mut, + instance, + "process_string", + &input, + ) + .unwrap(); + } }); }); } @@ -216,10 +203,13 @@ pub fn test_instances(c: &mut Criterion) { let mut jhs = Vec::new(); for _ in 0..25 { let input = input.clone(); - let instance = TestWasm::Test.instance(); + let instance_with_store = TestWasm::Test.instance(); + let instance = instance_with_store.instance.clone(); + let store = instance_with_store.store.clone(); let jh = std::thread::spawn(move || { let _: test_common::StringType = holochain_wasmer_host::guest::call( - Arc::clone(&instance), + &mut store.lock().as_store_mut(), + instance, "process_string", &input, ) diff --git a/test/src/wasms.rs b/test/src/wasms.rs index f38c55cd..97e5a975 100644 --- a/test/src/wasms.rs +++ b/test/src/wasms.rs @@ -14,6 +14,10 @@ use wasmer::Imports; use wasmer::Instance; use wasmer_middlewares::Metering; + +use std::sync::atomic::{AtomicUsize, Ordering}; +static INSTANCE_COUNTER: AtomicUsize = AtomicUsize::new(0); + pub enum TestWasm { Empty, Io, @@ -67,7 +71,10 @@ impl TestWasm { pub fn module(&self, metered: bool) -> Arc { match MODULE_CACHE.write().get(self.key(metered), self.bytes()) { - Ok(v) => v, + Ok(v) => { + // println!("using cached module for {}", self.name()); + v + }, Err(runtime_error) => match runtime_error.downcast::() { Ok(WasmError { error: WasmErrorInner::UninitializedSerializedModuleCache, @@ -112,6 +119,8 @@ impl TestWasm { } pub fn _instance(&self, metered: bool) -> InstanceWithStore { + let instance_count = INSTANCE_COUNTER.fetch_add(1, Ordering::SeqCst); + println!("creating instance for {} {}", self.name(), instance_count); let module_with_store = self.module(metered); let function_env; let instance; diff --git a/test/wasm_empty/src/wasm.rs b/test/wasm_empty/src/wasm.rs index e69de29b..b60bbdb9 100644 --- a/test/wasm_empty/src/wasm.rs +++ b/test/wasm_empty/src/wasm.rs @@ -0,0 +1,2 @@ +use holochain_wasmer_guest::allocation::__hc__allocate_1; +use holochain_wasmer_guest::allocation::__hc__deallocate_1; \ No newline at end of file