-
Notifications
You must be signed in to change notification settings - Fork 126
Expand file tree
/
Copy pathwasmtime_store_growth.rs
More file actions
157 lines (135 loc) · 4.28 KB
/
Copy pathwasmtime_store_growth.rs
File metadata and controls
157 lines (135 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright (C) Gear Technologies Inc.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
use criterion::{Criterion, criterion_group, criterion_main};
use gear_sandbox_env::{EnvironmentDefinition, Instantiate};
use gear_sandbox_host::{
context::{HostResult, SupervisorContext, SupervisorContextDispatcher, SupervisorFuncIndex},
sandbox::{GuestEnvironment, SandboxBackend, SandboxComponents},
};
use parity_scale_codec::Encode;
use sp_wasm_interface_common::{Pointer, WordSize};
use std::{
hint::black_box,
time::{Duration, Instant},
};
const EMPTY_WASM: &[u8] = b"\0asm\x01\0\0\0";
const MAX_OPERATIONS_PER_STORE: u64 =
(wasmtime::DEFAULT_INSTANCE_LIMIT as u64 + wasmtime::DEFAULT_MEMORY_LIMIT as u64) / 2;
#[derive(Clone, Copy)]
enum ResetPolicy {
Never,
Every(usize),
}
impl ResetPolicy {
fn as_str(self) -> &'static str {
match self {
Self::Never => "long_lived_store",
Self::Every(_) => "clear_periodically",
}
}
}
struct NoopSupervisor;
impl SupervisorContext for NoopSupervisor {
fn data_ptr(&self) -> *const () {
self as *const _ as *const ()
}
fn read_memory_into(
&self,
_address: Pointer<u8>,
dest: &mut [u8],
) -> std::result::Result<(), String> {
dest.fill(0);
Ok(())
}
fn write_memory(
&mut self,
_address: Pointer<u8>,
_data: &[u8],
) -> std::result::Result<(), String> {
Ok(())
}
fn allocate_memory(&mut self, _size: WordSize) -> std::result::Result<Pointer<u8>, String> {
Ok(Pointer::null())
}
fn deallocate_memory(&mut self, _ptr: Pointer<u8>) -> std::result::Result<(), String> {
Ok(())
}
}
impl SupervisorContextDispatcher for NoopSupervisor {
fn dispatch_thunk_id(&self) -> u32 {
0
}
fn invoke(
&mut self,
_invoke_args_ptr: Pointer<u8>,
_invoke_args_len: WordSize,
_func_idx: SupervisorFuncIndex,
) -> HostResult<i64> {
Ok(0)
}
}
fn bench_wasmtime_store_growth(c: &mut Criterion) {
let mut group = c.benchmark_group("wasmtime_store_growth");
for reset_policy in [ResetPolicy::Never, ResetPolicy::Every(50)] {
group.bench_function(reset_policy.as_str(), |b| {
b.iter_custom(|iters| {
let mut state = BenchState::new();
let mut elapsed = Duration::ZERO;
for i in 0..iters {
if i.is_multiple_of(MAX_OPERATIONS_PER_STORE) {
state = BenchState::new();
}
let instant = Instant::now();
state.run_iteration(i, reset_policy);
elapsed += instant.elapsed();
}
elapsed
})
});
}
group.finish();
}
struct BenchState {
store: SandboxComponents,
env_def: Vec<u8>,
supervisor: NoopSupervisor,
}
impl BenchState {
fn new() -> Self {
Self {
store: SandboxComponents::new(SandboxBackend::Wasmtime),
env_def: EnvironmentDefinition {
entries: Vec::new(),
}
.encode(),
supervisor: NoopSupervisor,
}
}
fn run_iteration(&mut self, iteration: u64, reset_policy: ResetPolicy) {
let memory_idx = self
.store
.new_memory(1, 1)
.expect("failed to create sandbox memory");
black_box(memory_idx);
let guest_env = GuestEnvironment::decode(&self.store, &self.env_def)
.unwrap_or_else(|_| panic!("failed to decode env"));
let instance = self
.store
.instantiate(
Instantiate::Version1,
EMPTY_WASM,
guest_env,
&mut self.supervisor,
)
.unwrap_or_else(|_| panic!("failed to instantiate empty wasm"));
let instance_idx = instance.register(&mut self.store, self.supervisor.dispatch_thunk_id());
black_box(instance_idx);
if let ResetPolicy::Every(clear_every) = reset_policy
&& iteration.is_multiple_of(clear_every as u64)
{
self.store.clear();
}
}
}
criterion_group!(benches, bench_wasmtime_store_growth);
criterion_main!(benches);