From 1216d66f1dffba878f07cfde9f96348317db1e2e Mon Sep 17 00:00:00 2001 From: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> Date: Wed, 30 Apr 2025 14:16:43 -0700 Subject: [PATCH] Add benchmark for guest call with large parameters Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> --- src/hyperlight_host/benches/benchmarks.rs | 37 ++++++++++++++++++- src/tests/rust_guests/simpleguest/src/main.rs | 24 ++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/hyperlight_host/benches/benchmarks.rs b/src/hyperlight_host/benches/benchmarks.rs index db71d8a95..22f0fd745 100644 --- a/src/hyperlight_host/benches/benchmarks.rs +++ b/src/hyperlight_host/benches/benchmarks.rs @@ -15,11 +15,12 @@ limitations under the License. */ use std::sync::{Arc, Mutex}; +use std::time::Duration; use criterion::{criterion_group, criterion_main, Criterion}; use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnType}; use hyperlight_host::func::HostFunction2; -use hyperlight_host::sandbox::{MultiUseSandbox, UninitializedSandbox}; +use hyperlight_host::sandbox::{MultiUseSandbox, SandboxConfiguration, UninitializedSandbox}; use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox; use hyperlight_host::sandbox_state::transition::Noop; use hyperlight_host::GuestBinary; @@ -69,6 +70,40 @@ fn guest_call_benchmark(c: &mut Criterion) { }); }); + // This benchmark includes time to first clone a vector and string, so it is not a "pure' benchmark of the guest call, but it's still useful + group.bench_function("guest_call_with_large_parameters", |b| { + const SIZE: usize = 50 * 1024 * 1024; // 50 MB + let large_vec = vec![0u8; SIZE]; + let large_string = unsafe { String::from_utf8_unchecked(large_vec.clone()) }; // Safety: indeed above vec is valid utf8 + + let mut config = SandboxConfiguration::default(); + config.set_input_data_size(2 * SIZE + (1024 * 1024)); // 2 * SIZE + 1 MB, to allow 1MB for the rest of the serialized function call + config.set_heap_size(SIZE as u64 * 15); + config.set_max_execution_time(Duration::from_secs(10)); + + let sandbox = UninitializedSandbox::new( + GuestBinary::FilePath(simple_guest_as_string().unwrap()), + Some(config), + None, + None, + ) + .unwrap(); + let mut sandbox = sandbox.evolve(Noop::default()).unwrap(); + + b.iter(|| { + sandbox + .call_guest_function_by_name( + "LargeParameters", + ReturnType::Void, + Some(vec![ + ParameterValue::VecBytes(large_vec.clone()), + ParameterValue::String(large_string.clone()), + ]), + ) + .unwrap() + }); + }); + // Benchmarks a guest function call calling into the host. // The benchmark does **not** include the time to reset the sandbox memory after the call. group.bench_function("guest_call_with_call_to_host_function", |b| { diff --git a/src/tests/rust_guests/simpleguest/src/main.rs b/src/tests/rust_guests/simpleguest/src/main.rs index 45dd558c7..6382cacd7 100644 --- a/src/tests/rust_guests/simpleguest/src/main.rs +++ b/src/tests/rust_guests/simpleguest/src/main.rs @@ -714,6 +714,22 @@ fn add(function_call: &FunctionCall) -> Result> { } } +// Does nothing, but used for testing large parameters +fn large_parameters(function_call: &FunctionCall) -> Result> { + if let (ParameterValue::VecBytes(v), ParameterValue::String(s)) = ( + function_call.parameters.clone().unwrap()[0].clone(), + function_call.parameters.clone().unwrap()[1].clone(), + ) { + black_box((v, s)); + Ok(get_flatbuffer_result(())) + } else { + Err(HyperlightGuestError::new( + ErrorCode::GuestFunctionParameterTypeMismatch, + "Invalid parameters passed to large_parameters".to_string(), + )) + } +} + #[no_mangle] pub extern "C" fn hyperlight_main() { let set_static_def = GuestFunctionDefinition::new( @@ -1108,6 +1124,14 @@ pub extern "C" fn hyperlight_main() { trigger_exception as usize, ); register_function(trigger_exception_def); + + let large_parameters_def = GuestFunctionDefinition::new( + "LargeParameters".to_string(), + Vec::from(&[ParameterType::VecBytes, ParameterType::String]), + ReturnType::Void, + large_parameters as usize, + ); + register_function(large_parameters_def); } #[no_mangle]