-
Notifications
You must be signed in to change notification settings - Fork 109
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
Track time spent in each wasm instance env call (#427)
Additionally, this further tidies the interface between the host and the wasm instance env. In particular, reducer calls are explicitly started and stopped, and the wasm instance env becomes responsible for its own instrumentation.
- vtest-tag
- vjdetter-test-tag
- v-kmullins-docker-tagging-test-3
- v1.0.0-rc2
- v1.0.0-rc2-hotfix1
- v1.0.0-rc1
- v1.0.0-rc1-hotfix3
- v1.0.0-rc1-hotfix2
- v1.0.0-rc1-hotfix1
- v0.12.0-beta-hotfix3
- v0.12.0-beta-hotfix2
- v0.12.0-beta-hotfix1
- v0.12.0-beta
- v0.11.1-beta
- v0.11.0-beta
- v0.10.1-beta
- v0.10.0-beta
- v0.9.2-beta
- v0.9.1-beta
- v0.9.0-beta
- v0.8.2-beta-hotfix7
- v0.8.2-beta-hotfix6
- v0.8.2-beta-hotfix5
- v0.8.2-beta-hotfix4
- v0.8.2-beta-hotfix3
- v0.8.2-beta-hotfix2
- v0.8.2-beta-hotfix1
- v0.8.2-beta
- v0.8.1-beta
- v0.8.0-beta-hotfix1
- v0.8.0-beta
- v0.7.3-beta-hotfix1
- v0.7.3-beta
- v0.7.2-beta
- v0.7.1-beta-hotfix1
- v0.7.1-beta
- test-tag
- release-alpha-4
- release-alpha-3
- release-alpha-2
- release-alpha-1
- alpha-playtest-3
1 parent
63ef6eb
commit b9bfe2c
Showing
8 changed files
with
310 additions
and
82 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
pub mod abi; | ||
pub mod instrumentation; | ||
pub mod module_host_actor; | ||
|
||
use std::time::Instant; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
//! This file defines `CallSpan` and `CallSpanStart`, | ||
//! which describe the time that a module spends executing "host calls," | ||
//! the WASM analog to syscalls. | ||
//! | ||
//! We can collect `CallSpan` timing data for various parts of host-call execution: | ||
//! - `WasmInstanceEnv`, responsible for direct communication between WASM and the host. | ||
//! - `InstanceEnv`, responsible for calls into the relational DB. | ||
//! - Others? | ||
//! | ||
//! The instrumentation has non-negligible overhead, | ||
//! so we enable it on a per-component basis with `cfg` attributes. | ||
//! This is accomplished by defining two interchangeable modules, | ||
//! `noop` and `op`, both of which implement the call-span interface. | ||
//! `noop` does nothing. | ||
//! `op` uses `std::time::Instant` and `std::time::Duration` to capture timings. | ||
//! Components which use the time-span interface will conditionally import one of the two modules, like: | ||
//! ```no-run | ||
//! #[cfg(feature = "spacetimedb-wasm-instance-times)] | ||
//! use instrumentation::op as span; | ||
//! #[cfg(not(feature = "spacetimedb-wasm-instance-times)] | ||
//! use instrumentation::noop as span; | ||
//! ``` | ||
use std::time::{Duration, Instant}; | ||
|
||
use enum_map::{enum_map, Enum, EnumMap}; | ||
|
||
#[allow(unused)] | ||
pub mod noop { | ||
use super::*; | ||
|
||
pub struct CallSpanStart; | ||
|
||
impl CallSpanStart { | ||
pub fn new(_call: Call) -> Self { | ||
Self | ||
} | ||
|
||
pub fn end(self) -> CallSpan { | ||
CallSpan | ||
} | ||
} | ||
|
||
pub struct CallSpan; | ||
|
||
pub fn record_span(_call_times: &mut CallTimes, _span: CallSpan) {} | ||
} | ||
|
||
#[allow(unused)] | ||
pub mod op { | ||
use super::*; | ||
|
||
pub struct CallSpanStart { | ||
call: Call, | ||
start: Instant, | ||
} | ||
|
||
impl CallSpanStart { | ||
pub fn new(call: Call) -> Self { | ||
let start = Instant::now(); | ||
Self { call, start } | ||
} | ||
|
||
pub fn end(self) -> CallSpan { | ||
let call = self.call; | ||
let duration = self.start.elapsed(); | ||
CallSpan { call, duration } | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct CallSpan { | ||
pub(super) call: Call, | ||
pub(super) duration: Duration, | ||
} | ||
|
||
pub fn record_span(times: &mut CallTimes, span: CallSpan) { | ||
times.span(span) | ||
} | ||
} | ||
|
||
/// Tags for each call that a `WasmInstanceEnv` can make. | ||
#[derive(Debug, Enum)] | ||
pub enum Call { | ||
CancelReducer, | ||
ConsoleLog, | ||
CreateIndex, | ||
DeleteByColEq, | ||
GetTableId, | ||
Insert, | ||
IterByColEq, | ||
IterDrop, | ||
IterNext, | ||
IterStart, | ||
IterStartFiltered, | ||
ScheduleReducer, | ||
} | ||
|
||
#[derive(Debug)] | ||
/// Associates each `Call` tag with a cumulative total `Duration` spent within that call. | ||
pub struct CallTimes { | ||
times: EnumMap<Call, Duration>, | ||
} | ||
|
||
impl CallTimes { | ||
/// Create a new timing structure, with times for all calls set to zero. | ||
pub fn new() -> Self { | ||
let times = enum_map! { _ => Duration::ZERO }; | ||
Self { times } | ||
} | ||
|
||
/// Track a particular `CallSpan` by adding its duration to the | ||
/// associated `Call`'s timing information. | ||
pub fn span(&mut self, span: op::CallSpan) { | ||
self.times[span.call] += span.duration; | ||
} | ||
|
||
/// Taking the record of call times gives a copy of the | ||
/// current values and resets the values to zero. | ||
/// | ||
/// WasmInstanceEnv::finish_reducer (and other future per-reducer-call metrics) | ||
/// will `take`` the CallTimes after running a reducer and report the taken times, | ||
/// leaving a fresh zeroed CallTimes for the next reducer invocation. | ||
pub fn take(&mut self) -> CallTimes { | ||
std::mem::replace(self, Self::new()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
b9bfe2c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmark results
Benchmark Report
Legend:
load
: number of rows pre-loaded into the databasecount
: number of rows touched by the transactionunique
: a single index on theid
columnnon_unique
: no indexesmulti_index
: non-unique index on every columnperson(id: u32, name: String, age: u64)
location(id: u32, x: u64, y: u64)
All throughputs are single-threaded.
Empty transaction
Single-row insertions
Multi-row insertions
Full table iterate
Find unique key
Filter
Serialize
Module: invoke with large arguments
Module: print bulk
Remaining benchmarks