open-standards/proof/proof-rs/crates/proof-cascade
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science 60bcca7594 proof-cascade: the meter reads its own process only once the measuring thread has left its core
measure_marginal's process-counter rung brackets its window with two
reads of this process's CPU energy (proc_pid_rusage ri_energy_nj). The
kernel adds a thread's energy to that count only when the thread leaves
a core, and a process's read of its own count does not take the reading
thread off its core. So the first read left up to a scheduling quantum
of what the measuring thread spent before the window (the liveness
probe's burn, the caller's own work) to land inside it, and the figure
is sealed HwShunt.

Measured on an M3 Ultra (macOS 27.0.1) with the meter's own read at each
end of a window on the reading thread, against the tests' own reader,
which sleeps before each read until the process's context-switch count
rose; three runs of 40 windows of each kind:
- 1 ms of the reading thread's CPU: all 40 read no advance, every run;
- a 2 ms sleep straight after 8 ms of CPU: all 40 read the burn before
  them, every run, 40 to 48 mJ for a sleep.

Each of the measurement's two reads now sleeps (50 us, then 200 us,
1 ms, 5 ms) until the measuring thread's own energy count (proc_pidinfo
PROC_PIDTHREADCOUNTS, read only in the one layout known: 88 bytes, two
performance levels here) rose across a sleep, and only then reads the
process. A read whose thread was not seen to leave gives the measurement
no figure, by the path an unreadable counter already takes: the work
does not run, measure_marginal returns None and the caller keeps its
estimate. The process counter is Unavailable where the thread's count
does not read (proof --measure says so), and the liveness probe still
samples with no sleep. The rule and the layout decoding are pure and
compiled on every platform.

The measurement was already one window around a batch: a second of
calls on every spare core, two reads in all. Its workers have exited and
been joined before the closing read, and a thread's exit puts its last
time on a core into the count before the join returns (measured: a 5 ms
burn read the same at the join whether or not the thread slept first),
so only the measuring thread needed taking off its core.

With it, on that host: quiet, every window read 98% or more of the
tests' window and no sleep more than 1% of the window that held the
burn; under 40 busy loops (110 runs), 82% or more and 4% or less. A
read costs about 80 us quiet and 190 us at the median under the busy
loops, against under 1 us.

process_window_read_nj is a doc-hidden hook, like the crate's other
test hooks: tests/process_energy_short_span.rs, the test that fails
without the check, needs a process of its own. The published
conformance vectors are unchanged (gen-vectors into a scratch directory
is byte-identical to conformance/v1).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 20:50:53 -04:00
..
src proof-cascade: the meter reads its own process only once the measuring thread has left its core 2026-10-12 20:50:53 -04:00
tests proof-cascade: the meter reads its own process only once the measuring thread has left its core 2026-10-12 20:50:53 -04:00
Cargo.toml Add the proof open standard — a carrier for verified work 2026-06-07 15:30:07 -04:00