ReviewOS

zig-utils/zig-js

Perf: measure cycles, cache behavior, energy, and thermal stability

#503
Closed chris opened this 8 days ago ·
8 days ago

Parent: #459 Depends on: #460, #461 Related: #478, #481, #486, #492, #502

Goal

Measure and improve work efficiency—cycles, instructions, cache behavior, context switching, energy, and thermal stability—alongside elapsed throughput.

Scope

  • Add an opt-in reference-host measurement layer for available hardware/OS counters: cycles, instructions, IPC, branches/misses, cache/TLB misses, context switches, migrations, scheduler waits, frequency/thermal state, package/process energy, and peak power where trustworthy.
  • Normalize counters by exact logical work/checksum and retain raw per-sample values with the existing alternating-order protocol.
  • Attribute counters to mutator, GC, JIT/Wasm compilation, runtime stubs, worker lifecycle, and idle/wait phases where the platform permits.
  • Record counter availability, permissions, multiplexing, sampling error, and unsupported hosts explicitly; never substitute zero.
  • Detect thermal/frequency drift and reject or annotate invalid comparisons before publication.
  • Add work-per-joule and cycles-per-operation panels without replacing wall-time, latency, scaling, or memory results.
  • Use owned collection/parsing code around standard platform interfaces; external profilers may remain diagnostic oracles, not dependencies.

No-workaround rules

  • No CPU-frequency lock or privileged host modification hidden from methodology, cherry-picked counter interval, discarded outlier without protocol, aggregate that hides a regressed row, or energy win purchased by doing less work.

Acceptance

  • Counter schema and host capability inventory distinguish measured, unavailable, permission-denied, and noisy/multiplexed data.
  • Repeated no-op/calibration and known-work fixtures validate counter boundaries and overhead.
  • Every retained efficiency claim links exact raw samples, hardware/power/thermal state, revisions, and logical-work normalization.
  • Instrumentation-disabled production path has measured zero/negligible overhead.
  • #460/#461 publication can require efficiency evidence for changes that materially add threads, code size, cache traffic, or CPU work.

Foundation

Existing benchmark reports record power source and dispersion but not microarchitectural or energy counters.

8 days ago

Initial owned counter ingestion landed in https://github.com/zig-utils/zig-js/commit/5be57aa8cd074b342a443c510d8653bf45e7ed54. The instrumentation-overhead fixture now captures macOS retired instructions, cycles, and voluntary/involuntary context switches directly from /usr/bin/time -l for every alternating raw sample, normalized by frozen logical work. No missing value becomes zero, and quick results are validation-only. This advances the counter/schema foundation; capability classification, calibration/noise/multiplexing controls, cache/TLB/energy/thermal collection, and full evidence remain open.

8 days ago

Seven-pair full-work diagnostic counter evidence is now checked in via https://github.com/zig-utils/zig-js/commit/8eb68138. Every raw sample retains retired instructions, cycles, and voluntary/involuntary context switches normalized to 2,200 frozen jobs, with exact runner/workload hashes and revision metadata. The battery/discharging host is explicitly diagnostic, so this advances ingestion and provenance but makes no stable efficiency claim.

8 days ago

Capability classification and calibration landed in https://github.com/zig-utils/zig-js/commit/358c5f0f9dc85d82328f8e899d835fd9fef603ef.

The instrumentation-overhead artifact is now schema v2. Each retained OS counter observation is measured, unavailable, or permission_denied; capability availability, multiplexing metadata, and sample quality are separate fields. Repeated locale-controlled /usr/bin/time -l /usr/bin/true no-op probes and the exact disabled known-work samples are both retained, with a 5% RSD threshold classifying data as stable, noisy, or indeterminate. No sample is discarded and no unavailable counter becomes zero.

The macOS capability inventory records instructions, cycles, and voluntary/involuntary context switches through time -l. Because that interface exposes no scaling or multiplexing metadata, the artifact records multiplexing as unavailable rather than assuming counters are not multiplexed. Branches/misses, cache/TLB misses, migrations, scheduler waits, frequency, thermal state, energy, and peak power are explicitly unavailable through this unprivileged process-boundary interface.

A real two-pair battery-host diagnostic run exercised the production collector: instructions were stable in both no-op and known-work calibration; cycles were noisy for no-op and stable for known work; context-switch quality was indeterminate/noisy. Those quick values are validation-only and support no efficiency claim.

Validation passed: instrumentation self-test, real collector run, full benchmark-comparison-test, dependency audit, 100-file docs link audit, and the 49-page checked-manifest docs build. This implements the calibration/known-work acceptance slice and advances capability classification; trustworthy cache/TLB/energy/thermal collection and publication enforcement remain open.

8 days ago

Owned process-energy collection landed in https://github.com/zig-utils/zig-js/commit/1ee893b4f8e1926ca503d314adb83d79ee63370f.

The ReleaseFast runner now snapshots its exact public proc_pid_rusage(RUSAGE_INFO_V6) layout immediately before and after the timed JavaScript invocation. Schema v3 retains instructions, cycles, cumulative process energy (nJ), package/interrupt wakeups, page-ins, and VM page-cache hits from that owned boundary; /usr/bin/time -l remains the independent source for process CPU, peak RSS, and context switches. CPU cache/TLB events, branches, migrations, scheduler wait, frequency, package energy, peak power, and thermal state remain explicit unavailable capabilities. VM page-cache hits are not presented as CPU cache behavior.

The runner-owned no-op boundary and frozen known-work samples are both repeated and retained. Derived panels normalize cycles, instructions, and process energy by exact logical jobs/checksum and include instructions/cycle and jobs/joule. A quiet-reference artifact now fails closed unless it is on AC power and known-work instructions, cycles, and process energy are all measured and stable at the 5% RSD threshold.

A clean quick diagnostic at exact zig-js revision 1ee893b4f8e1926ca503d314adb83d79ee63370f, zig-gc c89a10fc4454bfba3d28183cfa7fade08fab8aa4, and zig-regex 719673318b0c6250898d7ced3603876c148e370b retained all two alternating pairs and both no-op samples with the frozen checksum. Raw JSON: /tmp/zig-js-issue503-rusage-1ee893b4.json, 25,589 bytes, SHA-256 6ae4830e733df2f6286a060b260e160b5a782cb13ca8b75c11d7753842cc1491; runner SHA-256 9fda4fddd94992bf341de3470c602153596781bdcc4d1d729bf4601b43d1fff5. Instructions and cycles classified stable for known work; process energy classified noisy. The host was battery/discharging and the run was quick, so it is diagnostic only and supports no efficiency ratio claim.

Validation passed: named SDK layout/size assertions, live no-op and known-work probes, the real collector, full benchmark-comparison-test, 100-file docs link audit, and the checked 49-page docs build. This implements the trustworthy process-energy and logical-work-normalization slice. Thermal-state capture, exact-parent efficiency publication enforcement for material CPU/thread/code/cache changes, and any unavailable platform counters remain open.

8 days ago

Public thermal-state collection landed in https://github.com/zig-utils/zig-js/commit/61ff9e704a2e329bd19315a3a1daa416e789775b.

The benchmark runner now captures NSProcessInfo.thermalState immediately before and after every no-op and known-work boundary. Both Foundation queries sit outside the wall-time interval and outside the proc_pid_rusage process-counter snapshots, so collection does not contaminate either measured boundary. Schema v4 retains each categorical before/after observation, classifies within/across-sample drift, and rejects quiet-reference publication unless the entire run is measured, stable, and nominal. Fair/serious/critical state, any transition, unavailable state, battery power, or noisy instructions/cycles/process energy all fail closed for reference-host claims.

A clean two-pair diagnostic at exact zig-js revision 61ff9e704a2e329bd19315a3a1daa416e789775b retained all raw samples and no-op calibrations. Raw JSON: /tmp/zig-js-issue503-thermal-61ff9e70.json, 26,979 bytes, SHA-256 bc04d0fe205c9e09b3d11118b2039eae004896347d176fe379afae115f39514e; runner SHA-256 c77409028454d44c5bda35988d2717efb5d76f686ac29d85307249f85802ad45. No-op, disabled, and enabled observations were all nominal → nominal; thermal quality classified stable. Instructions and cycles were stable for known work, while process energy was noisy. The host was battery/discharging and the run was quick, so it supports no efficiency ratio claim.

Validation passed: thermal drift/non-nominal fail-closed fixtures, live no-op/known-work/ordinary-path probes, the real collector, full benchmark-comparison-test, 100-file docs link audit, and the checked 49-page docs build. This completes trustworthy thermal-state detection and publication rejection. Exact-parent efficiency publication enforcement for material thread/code/cache/CPU changes and explicitly unavailable CPU cache/TLB/package-power counters remain open.

8 days ago

Exact-parent efficiency publication enforcement landed in https://github.com/zig-utils/zig-js/commit/d3d02b52f906d1629771c26b70005da819c7407d, followed by the live-discovered native timing parser fix in https://github.com/zig-utils/zig-js/commit/19665e69318b638f771fa9adf3bf7087220edb95.

Every scored runner boundary now supports the same opt-in telemetry for single, independent steady/cold, shared-realm, and module-cold modes. Exact-parent artifacts measure instructions, cycles, process energy, and before/after thermal state alongside wall/CPU/RSS, with exact parent/candidate order, binary/source hashes, revisions, logical work, and checksum. Reference-host publication recomputes RSD and thermal validity from raw samples; a forged summary cannot bypass the gate.

Material-change categories are cpu_work, threads, generated_code, and cache_traffic. CPU/thread claims require stable parent and candidate instructions, cycles, process energy, and nominal->nominal thermal state. Generated-code and cache-traffic claims additionally require stable generated_code_bytes or cache_misses; those categories fail closed while the exact metric is unavailable. Diagnostic hosts retain every row but never gate or support a publication claim.

The first real clean exact-parent diagnostic compared candidate 19665e69318b638f771fa9adf3bf7087220edb95 with its literal first parent d3d02b52f906d1629771c26b70005da819c7407d. Because the candidate changes only the owned timing parser, both revisions correctly use the same runner binary SHA-256 7956b77153594fdc4c27d1bf11c9daa2ed0c4a23d4ac65e59ec47132d1aca9d2. It retained two alternating pairs at 110 frozen jobs/checksum 5864992; instructions, cycles, and process energy each classified stable for parent and candidate, every thermal observation was nominal->nominal, and no category metric was unmet. The host was battery/discharging and wall samples were noisy, so status is diagnostic_only and no ratio claim is made. Raw JSON: /tmp/zig-js-issue503-exact-parent-19665e69.json, 55,379 bytes, SHA-256 95f2ed0505b0299e835a3ab12f98ca8a8be8b390bc42d0447950665683cd53cf.

The instrumentation-disabled production path is already measured by the checked seven-pair full-work artifact docs/.data/instrumentation-overhead-diagnostic-2026-08-04.json: enabled/disabled medians are 0.9892x wall, 1.0000x process user CPU, and 1.0000x peak RSS, with the exact same binary and no applicable single-thread contention. The ordinary runner path performs no counter/thermal query and emits no telemetry row; collection remains opt-in.

Validation passed: real telemetry in all four runner-mode families, combined macOS time -l parsing, thermal/noise/category fail-closed fixtures, independent raw-artifact revalidation, full benchmark-comparison-test, 100-file docs link audit, and the checked 49-page docs build. All acceptance items are now implemented without privileged host changes, discarded samples, hidden unavailable metrics, or workload changes.

Sign in to comment on this issue.