Skip to main content

Module perf

Module perf 

Source
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§

FakeClock
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, …
FrameRecord
What one frame measured. Build it with FrameRecord::new (ADR-0039).
FrameTimes
How long the parts of one frame took, in whole microseconds. Build it with FrameTimes::new (ADR-0039); a backend may add a part.
HeapCounts
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).
HeapDiff
What grew and shrank in the heap between two snapshots (HeapSnapshot::diff). Build an empty one with HeapDiff::new (ADR-0039).
HeapSnapshot
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 with diff.
MemoryReading
What a backend reads of the device’s memory at a frame’s end (shuyi_platform::Platform::memory). Build it with MemoryReading::new (ADR-0039).
MemoryScopes
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 with MemoryScopes::new (ADR-0039).
PerfRing
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 records since the last it took.
SpanEvent
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 with TagRow::new (ADR-0039).

Enums§

PerfClock
A clock in whole microseconds, from a backend (shuyi_platform::Platform::clock) or a test.
PerfLine
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); Other is 0, the class of the counter’s own other and overflow.

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 PerfRing keeps by default: ten seconds at 60 a second.

Functions§

bytes_text
bytes for people: under 1,024 as 1023 B, then in KB, MB and GB with one decimal, rounded down (1.0 KB is 1,024 bytes, 1.0 MB 1,048,576), in integers.
spread
How values spread, or None for no values. The percentiles are nearest-rank: the value at rank ⌈p × n / 100⌉ of the n values sorted, all in integers.