Expand description
Frame times and spans as data (ADR-0046), in debug builds: what the
platform’s App measures of each frame and keeps in a PerfRing of
the last PERF_FRAMES FrameRecords, for tests, tools and agents.
Only a backend has a clock. It hands one over (PerfClock), the
platform’s App moves it into the game’s context, and the context reads
it: around the update and the drawing, and around each span a game
marks. With debug tools off (Ctx::debug_tools) nothing is measured
and the clock is never read.
A game marks a span of its own around any part of an update:
use shuyi_ui::{Ctx, GameData};
fn plan_turn<G: GameData>(ctx: &mut Ctx<G>) -> u32 {
ctx.span("ai", |_ctx| 2 + 2)
}Ctx::span calls the closure and gives back what it returns; in a
measured frame it also keeps the span’s start, length and depth in the
frame’s record. A time never reaches an update: nothing reads a record
to decide anything, so a run plays the same with the clock on and off.
The heap is counted too, where the backend counts it (a debug build of
shuyi-app or of a game’s tool program): each record’s
heap holds the live bytes, their peak and the
allocations in that frame (HeapCounts), as the backend’s
MemoryReading gave them at the frame’s end. The counter counts the
whole process, every thread’s allocations.
Where the backend’s counter has memory tags (MemoryScopes), it
also counts what each part of a frame allocates under a tag of its own
(TagClass): the frame’s phases, each span a game marks, and each
asset kind the backend sees decoded. Entering a tag changes nothing a
game reads. A HeapSnapshot is what holds the heap at a frame, by
tag, and a HeapDiff what grew and shrank between two
(HeapSnapshot::diff); both are lines of a trace (PerfLine).
Structs§
- Fake
Clock - A clock for tests. It starts at 0, and its read number n (from 0) adds 100 × (n mod 7 + 1) microseconds and gives the new time: 100, 300, 600, 1000, …
- Frame
Record - What one frame measured. Build it with
FrameRecord::new(ADR-0039). - Frame
Times - How long the parts of one frame took, in whole microseconds. Build it
with
FrameTimes::new(ADR-0039); a backend may add a part. - Heap
Counts - The heap’s counts at a frame’s end, in bytes asked for (never the
allocator’s own overhead). Build it with
HeapCounts::new(ADR-0039). - Heap
Diff - What grew and shrank in the heap between two snapshots
(
HeapSnapshot::diff). Build an empty one withHeapDiff::new(ADR-0039). - Heap
Snapshot - What holds the heap at a frame (ADR-0046 §6): its live bytes, and each
memory tag’s counts. Build it with
HeapSnapshot::new(ADR-0039), which puts the rows in order; compare two withdiff. - Memory
Reading - What a backend reads of the device’s memory at a frame’s end
(
shuyi_platform::Platform::memory). Build it withMemoryReading::new(ADR-0039). - Memory
Scopes - How a backend lets the engine tag what it allocates (ADR-0046 §6):
three plain functions over its heap counter’s tags
(
shuyi_platform::Platform::memory_scopes), so neither this crate nor the platform depends on the counter. Build it withMemoryScopes::new(ADR-0039). - Perf
Ring - The last frames’ records, oldest first, and how many older ones were
dropped:
LogRing’s twin. Each record pushed gets a sequence number, from 0 and never reused, so a reader takes the recordssincethe last it took. - Span
Event - A span a game marked (
Ctx::span), as it ended. - Spread
- How a set of times spread, in whole microseconds: the median, the 99th percentile (nearest rank), the worst and the mean rounded down.
- TagDelta
- How one memory tag changed between two snapshots. Build it with
TagDelta::new(ADR-0039). - TagRow
- One memory tag’s counts in a
HeapSnapshot, in bytes asked for. Build it withTagRow::new(ADR-0039).
Enums§
- Perf
Clock - A clock in whole microseconds, from a backend
(
shuyi_platform::Platform::clock) or a test. - Perf
Line - One line of a perf trace, as agents read it (ADR-0046 §7): a JSON
object tagged by
kind, one a line (serde_json::to_string(&line)and a newline). - TagClass
- What a memory tag names (ADR-0046 §6): the heap counter counts each
block under the innermost tag entered when it was allocated. Its number
is the class a backend’s counter keeps with each name
(
MemoryScopes::tag);Otheris 0, the class of the counter’s ownotherandoverflow.
Constants§
- MAX_
SPANS - How many spans a frame’s record keeps: those past it are counted in
FrameRecord::spans_dropped. - PERF_
FRAMES - How many frames’ records a
PerfRingkeeps by default: ten seconds at 60 a second.
Functions§
- bytes_
text bytesfor people: under 1,024 as1023 B, then inKB,MBandGBwith one decimal, rounded down (1.0 KBis 1,024 bytes,1.0 MB1,048,576), in integers.- spread
- How
valuesspread, orNonefor no values. The percentiles are nearest-rank: the value at rank ⌈p × n / 100⌉ of the n values sorted, all in integers.