Skip to content

Commit 9d05679

Browse files
committed
Add benchmark for guest call with large parameters
Signed-off-by: Ludvig Liljenberg <[email protected]>
1 parent 24586f5 commit 9d05679

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

src/hyperlight_host/benches/benchmarks.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ limitations under the License.
1515
*/
1616

1717
use std::sync::{Arc, Mutex};
18+
use std::time::Duration;
1819

1920
use criterion::{criterion_group, criterion_main, Criterion};
2021
use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnType};
2122
use hyperlight_host::func::HostFunction2;
22-
use hyperlight_host::sandbox::{MultiUseSandbox, UninitializedSandbox};
23+
use hyperlight_host::sandbox::{MultiUseSandbox, SandboxConfiguration, UninitializedSandbox};
2324
use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox;
2425
use hyperlight_host::sandbox_state::transition::Noop;
2526
use hyperlight_host::GuestBinary;
@@ -69,6 +70,40 @@ fn guest_call_benchmark(c: &mut Criterion) {
6970
});
7071
});
7172

73+
// 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
74+
group.bench_function("guest_call_with_large_parameters", |b| {
75+
const SIZE: usize = 50 * 1024 * 1024; // 50 MB
76+
let large_vec = vec![0u8; SIZE];
77+
let large_string = unsafe { String::from_utf8_unchecked(large_vec.clone()) }; // Safety: indeed above vec is valid utf8
78+
79+
let mut config = SandboxConfiguration::default();
80+
config.set_input_data_size(2 * SIZE + (1024 * 1024)); // 2 * SIZE + 1 MB, to allow 1MB for the rest of the serialized function call
81+
config.set_heap_size(SIZE as u64 * 15);
82+
config.set_max_execution_time(Duration::from_secs(3));
83+
84+
let sandbox = UninitializedSandbox::new(
85+
GuestBinary::FilePath(simple_guest_as_string().unwrap()),
86+
Some(config),
87+
None,
88+
None,
89+
)
90+
.unwrap();
91+
let mut sandbox = sandbox.evolve(Noop::default()).unwrap();
92+
93+
b.iter(|| {
94+
sandbox
95+
.call_guest_function_by_name(
96+
"LargeParameters",
97+
ReturnType::Void,
98+
Some(vec![
99+
ParameterValue::VecBytes(large_vec.clone()),
100+
ParameterValue::String(large_string.clone()),
101+
]),
102+
)
103+
.unwrap()
104+
});
105+
});
106+
72107
// Benchmarks a guest function call calling into the host.
73108
// The benchmark does **not** include the time to reset the sandbox memory after the call.
74109
group.bench_function("guest_call_with_call_to_host_function", |b| {

src/tests/rust_guests/simpleguest/src/main.rs

+24
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,22 @@ fn add(function_call: &FunctionCall) -> Result<Vec<u8>> {
714714
}
715715
}
716716

717+
// Does nothing, but used for testing large parameters
718+
fn large_parameters(function_call: &FunctionCall) -> Result<Vec<u8>> {
719+
if let (ParameterValue::VecBytes(v), ParameterValue::String(s)) = (
720+
function_call.parameters.clone().unwrap()[0].clone(),
721+
function_call.parameters.clone().unwrap()[1].clone(),
722+
) {
723+
black_box((v, s));
724+
Ok(get_flatbuffer_result(()))
725+
} else {
726+
Err(HyperlightGuestError::new(
727+
ErrorCode::GuestFunctionParameterTypeMismatch,
728+
"Invalid parameters passed to large_parameters".to_string(),
729+
))
730+
}
731+
}
732+
717733
#[no_mangle]
718734
pub extern "C" fn hyperlight_main() {
719735
let set_static_def = GuestFunctionDefinition::new(
@@ -1108,6 +1124,14 @@ pub extern "C" fn hyperlight_main() {
11081124
trigger_exception as usize,
11091125
);
11101126
register_function(trigger_exception_def);
1127+
1128+
let large_parameters_def = GuestFunctionDefinition::new(
1129+
"LargeParameters".to_string(),
1130+
Vec::from(&[ParameterType::VecBytes, ParameterType::String]),
1131+
ReturnType::Void,
1132+
large_parameters as usize,
1133+
);
1134+
register_function(large_parameters_def);
11111135
}
11121136

11131137
#[no_mangle]

0 commit comments

Comments
 (0)