[M1-BENCH-01] laige-bench sim-tick suite: 10k-entity tick budget on both SimMath backends - #52
Merged
Merged
Conversation
…oth SimMath backends
The PRD 8.1 simulation-tick workload as a laige-bench suite: 10k entities
(2k dynamic bodies with Position2D + velocity, 8k bare), 60 Hz through
the GameLoop on an exact synthetic clock, BenchMove + BenchHash (per-tick
state hash) systems, 3000 measured ticks after 1000 warm-up, checked
against sim_tick_avg (<=3.0 ms) and sim_tick_p99 (<=5.0 ms) on BOTH
SimMath backends (ADR 0002). In debug non-sanitizer builds every measured
tick additionally passes the engine's own G-R1 per-tick zero-allocation
assertion (M1-ALLOC-01).
Tool: new --math=<fixed_point_16_16|float_pinned_32> option, repeatable
--budget (one run gates every named budget against the same histogram),
suite setup/teardown hooks, compiler-id fix (Clang before GCC — Clang 22's
__VERSION__ is 'Clang 22.1.8' and the old order mislabeled clang builds).
CI gate: laige_bench_sim_tick_{fpx16,fp32} ctest entries in every
non-instrumented P0 job's full ctest (excluded from ASan/TSan trees —
instrumentation inflates the tick cost, the m1-profiler-cost precedent);
a budget FAIL exits 2 and fails the job (PRD 8.1 regression gate).
Results (canonical Debug g++ 16.2.1, AMD Ryzen 9 7950X3D):
fpx16_16 mean=0.59283 ms p99=0.618314 ms
fp32_pinned mean=0.589047 ms p99=0.605951 ms
Both backends PASS (5.1x / 8.1x inside the budgets). The run's final_hash
is bit-identical across all non-instrumented local trees and both
compilers, at both backends.
budgets.json measured (worse of the two backends, first recorded values):
sim_tick_avg 0.59283 ms / sim_tick_p99 0.618314 ms.
Fourth baseline: docs/benchmarks/baselines/m1-sim-tick.md (full AGENTS
12 metadata, verbatim runs, cross-tree/cross-compiler table). Docs
updated: benchmarks READMEs, budget_harness.md.
M1-BENCH-01 is complete (sim-tick suite, both SimMath backends, first recorded budgets.json measured values, fourth baseline) and CI-verified (PR lane run 36152843429: linux-gcc/clang full ctest green including the two sim_tick budget gate entries, detcheck both-backend baselines, sanitizer lanes, lints, API manifest). Progress Board: M1 25/25 complete (the board Total row also corrected 41 -> 47, which had gone stale across the last M1 steps). The gate's Recorded evidence block (the three CI links) lands in this PR's follow-up commit once the full P0-matrix run (ci:macos + ci:windows labels) is green.
The initial-state formula stacked the 2 000 dynamic bodies in a single grid column: x = (i / 2000) % 50 - 25 is 0 for every i < 2000, so the bodies never spread over the documented 50x50 grid (one body per cell of the first 2000 cells). Fixed to x = (i / 50) % 50 - 25 (column-major over the grid span), matching the documented workload. Re-measured on every tree after the fix (the initial state changed, so the final_hash fingerprints changed — determinism across trees and compilers re-verified, bit-identical again): canonical Debug g++ 16.2.1: fpx16_16 mean 0.598405 / p99 0.606001, fp32_pinned mean 0.591438 / p99 0.615179 (both budgets PASS, 5.0x / 8.1x inside target); Release 0.0801/0.0844; Clang 0.9133/0.9360; shared 0.6237/0.6393; ASan leak-free 1.6397; TSan race-free 2.4497. Numbers moved <2% (the iteration cost is archetype-bound, not position-value-bound); the budget result is unchanged. budgets.json measured updated to the post-fix values (worse of the two backends): sim_tick_avg 0.598405, sim_tick_p99 0.615179. The baseline doc and the M1-BENCH-01 changelog line carry the corrected values, and the baseline's Interpretation records the fix (same PR, before merge).
…S evidence) The PR-lane label protocol runs one P0 OS family per run: no labels = linux-gcc/clang/asan/tsan, ci:windows (no ci:macos) = windows-msvc, ci:macos = macos-arm64/intel. The M1-EXIT-01 gate requires replay bit-exactness evidence on every P0 OS job for this PR's code; the Linux lane ran on 36152843429 (c2287c1), the macOS pair on 36155154836 (this commit's parent), this empty commit selects the Windows lane.
The three gate items, with their CI evidence links: (1) sim-tick budget green on both SimMath backends — the baseline report + PR-lane runs 36152843429 (linux-gcc/clang full ctest 94/94 with the two budget-gate entries) and 36155154836 (macOS arm64/Intel full ctest, same entries green on AppleClang); the CI reference machine (ubuntu-24.04) is the gate. (2) replay bit-exact on CI across all P0 OS jobs and both backends — the determinism matrix + merge-lane run 36037080146 (all 7 P0 jobs + detcheck on master) and this PR's label-gated P0 matrix: Linux run 36152843429, macOS arm64/Intel run 36155154836, windows-msvc run 36156322585 — every job green, including hello_baseline_fpx/fp32 in each OS job's ctest and the detcheck job (both backends). (3) zero-alloc assertion green on the 10k workload — the zero_alloc ctest entry green in every P0 job's full ctest in the runs above, and the M1-BENCH-01 measurement itself zero-alloc-asserted per tick (G-R1). Deferred P1 items: none — every M1 step is P0. Progress Board: M1 25/25 complete (total 47/193), set in the prior commit; the M1-BENCH-01 changelog line's stale 1.6/0.59 ms ASan mention corrected to the post-fix 1.64/0.60 ms in the same change.
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements M1-BENCH-01 (roadmap/M1-heartbeat.md).
What
The PRD §8.1 "Simulation tick" workload as a
laige-benchsuite (--suite=sim-tick):Position2D<B>+ aBenchVel<B>component, both marked deterministic-safe), 8 000 bare entities; deterministic seed 0x1F055EED, index-derived initial state (no RNG in the measured path).BenchMove(1 ms budget,pos += velvia the active backend'sSimMath::add) andBenchHash(2 ms budget, the per-tickWorld::stateHash).GameLoopat 60 Hz on an exact synthetic clock (one due tick/frame); one measured sample = one completed tick; 1 000 warm-up + 3 000 measured ticks.--math=fixed_point_16_16/float_pinned_32), both must pass (ADR 0002).Tool changes
--math=<fixed_point_16_16|float_pinned_32>— SimMath backend selection for the sim-tick suite (default fpx16).--budget=<name>— one run checks every named budget against the same histogram (the M1 gate: avg AND p99 in one run); duplicate name = usage error; any FAIL exits 2.__GNUC__and its__VERSION__is "Clang 22.1.8" — the old order mislabeled clang builds as "GCC Clang 22.1.8").CI gate
New ctest entries
laige_bench_sim_tick_fpx16/laige_bench_sim_tick_fp32(canonical 3000/1000 shape, both budgets, repo-root budgets.json viaLAIGE_BUDGETS_PATH) run in every non-instrumented P0 job's full ctest — this is the PRD §14 CI perf lane for the sim tick. Excluded from the ASan/TSan trees: instrumentation inflates the tick's absolute cost (~2.7× under ASan+UBSan), so a sanitizer measurement would measure the instrumentation, not the sim (the m1-profiler-cost precedent). A budget FAIL exits 2 and fails the CI job.Results (canonical Debug, g++ 16.2.1, AMD Ryzen 9 7950X3D / CachyOS)
Both backends PASS (5.1× / 8.1× inside the budgets). The run's
final_hashfingerprint is bit-identical across all four non-instrumented local trees and both compilers (g++ 16.2.1 / Clang 22.1.8), at both backends (fpx160x8aa6b855aa807b31, fp320x34ff9f20dac09426).budgets.jsongains its first recordedmeasuredvalues (worse of the two backends):sim_tick_avg0.59283,sim_tick_p990.618314.Baseline + docs
docs/benchmarks/baselines/m1-sim-tick.md— full AGENTS §12 metadata, verbatim budget-checked runs, the ctest gate, cross-tree/cross-compiler table, interpretation. Records that M1 measures the ECS-only slice of the §8.1 workload (kinematic movement + state hash; physics lands in M3, presentation in M4).docs/benchmarks/README.md+docs/benchmarks/baselines/README.md— stale "every entry still measured: 0" text replaced; the missing m1-profiler-cost baseline entry added.docs/api/budget_harness.md— the new CLI form, the sim-tick suite, the measured-field note, both suites' determinism.Local verification
Full ctest green on all six local trees: 94/94
build/build-clang/build-shared, 93/93build-release, 92/92build-asan/build-tsan(gate entries correctly absent there); ASan run leak-free, TSanhalt_on_error=1race-free (one legitimate G-R5budget_overrunwarn on BenchHash under the 4× TSan slowdown — correct engine observation); zero new warnings under NFR-8.10; include-lint + determinism-lint OK; no new public API (laige-api.json unchanged).