You run unattended for hours. Each wake-up does one item: measure, fix,
verify, commit, record. The tracker is the memory between wake-ups, because
your context is compacted along the way. Follow AGENTS.md in full; this file
only adds to it.
- Work only in
/home/vasylt/Code/rusting/RustingEngine-performanceon branchlane/performance. Never edit, commit to, merge into or pushmainor any other lane's folder. The owner merges. - Tracker:
performanceImprovement.mdin the lane, committed with the work.
cd /home/vasylt/Code/rusting/RustingEngine-performance, check thatgit statusis clean, thengit rebase main.- Copy
/home/vasylt/Code/rusting/RustingEngine/performanceImprovement.mdinto the lane. Append a## Loop logsection at the end, then commit it alone: "Add the v2.6.0 performance plan".
-
Orient. Run
cdto the lane. Ifgit statusis not clean, a previous wake-up was cut off. Read the last## Loop logentry and either finish that item orgit stash push -m "<ID> interrupted"and log it. Then rungit rebase main. On a conflict that is not trivial, rungit rebase --abort, log it, and continue on the current base. -
Pick. Take the first open (
- [ ]) item in the order of "Order and lanes", then by phase. Skip:- items in "Owner decisions" (see below),
- items marked
[-](blocked) or[x](done), - items another lane holds (
scripts/lane.sh claims).
Claim it with
scripts/lane.sh claim "<ID>". Before you continue, read every file the item touches and trace the real flow end to end. Line numbers in the tracker drift. -
Measure before. Use the command in the item's gate or verify line. Otherwise use the closest benchmark below. Record the exact command and the result.
-
Fix. Make the smallest change that removes the cost at its root.
- Add no dependency.
- Keep the physics determinism rules. The bit-identical guards in "Ground rules" must pass unchanged, unless the item says it re-records them.
- Golden images stay unchanged, unless the item is a declared quality trade.
- Every change in editor scene edits goes through the snapshot undo.
- Add the smallest test that fails if the gain regresses (a counter, a call count, an allocation or byte count) when the item has no test yet.
-
Measure after, with the same command. Take the median of 3 runs for times. Counters need one run.
-
Full check. Run every command in the AGENTS.md full check, with the gpu-tests run through
flock /tmp/rusting-gpu.lock. -
Decide.
- It passes and the number moved: tick the item
[x]in the tracker. Under the item, addDone:with the before and after numbers, the command, and the test names. Add one line to theCHANGELOG.md[Unreleased]### Changedsection when users can feel the change. Commit one item per commit, and end the message withCo-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>. Then runscripts/lane.sh done "<ID>". - The check fails and you cannot fix it inside the item, or the gain is
under the noise: run
git stash push -m "<ID> <reason>". Mark the item[-]with oneBlocked:line naming the reason and the stash. Commit only the tracker, drop the claim, and move on. Never loop on one item: after 3 failed attempts, block it. - The item is too big for one commit (most of Phase 3): split it
into
<ID>a,<ID>band so on under the item. Do the first part now.
- It passes and the number moved: tick the item
-
Log. Append one line to
## Loop log: date and time, ID, result, commit hash, and the next item. -
Continue. Call ScheduleWakeup with
delaySeconds: 60, then end the turn.
You must also find work that is not in the tracker yet.
- Run the benchmark set below, and compare it with the Baseline and Round 2 tables.
- Profile the worst case with Nsight Systems on a frame-pointer build:
RUSTFLAGS="-C force-frame-pointers=yes" cargo build --release --example <name>, thennsys profile --sample=cpu --trace=vulkan,osrt -o <scratch>/<name> <binary> .... Read the top self and inclusive functions withnsys stats. - Read code that no round has audited yet.
grepfor these patterns:clone()in per-frame loopsVec::new,collectorformat!in per-frame or per-tick pathsHashMapwith SipHash on hot paths- linear
findorpositionscans on large lists world.querywithout a cached state- work done every frame with no change check
- For each new cost above 2% of a frame or step, or above 1 MB a frame,
append an item with prefix P (P1, P2, …) under
## Found by the loopin the tracker. Use the same form as the other items: the problem with a file and line, the evidence number, the fix, and a gate. - Commit the tracker alone ("Add loop findings P-P").
Write every output to target/perf-loop/, never to benchmarks/.
render_bench compares against an existing JSON file, and writes the file
when it does not exist. Use a new file name per run, or delete the old file.
flock /tmp/rusting-gpu.lock cargo run --release --example render_bench -- eco target/perf-loop/<ID>-<n>-eco.json
flock /tmp/rusting-gpu.lock cargo run --release --example render_bench -- high target/perf-loop/<ID>-<n>-high.json
flock /tmp/rusting-gpu.lock cargo run --release --example render_bench -- eco target/perf-loop/<ID>-<n>-bears.json --bears 50000 --bear-updates 50
flock /tmp/rusting-gpu.lock env RUSTING_PERF=1 cargo run --release --features window --example physics_bench -- falling 100000
cargo run --release --example physics_suite- The GPU is shared with jobs outside the lock. Before timing, run
nvidia-smi --query-compute-apps=pid,process_name --format=csv. Note any other job next to the numbers. Counters (bytes, draws, dispatches, calls) are exact, so trust them over times. /tmpis a 16 GB tmpfs. Keep Nsight files in the session scratchpad, and delete them after you read them. Keeptarget/perf-loop/under 1 GB.
X1, X5, X17 and any new dependency or build-profile change need the owner's
approval. Run the measurement the tracker names (for X5, the LD_PRELOAD
jemalloc and tcmalloc runs), write the result under the item, and leave it
[ ]. Treat any other change that needs a format break, a re-recorded hash,
or a visible quality loss the same way, unless the item already approves it.
Call ScheduleWakeup with stop: true when one of these is true:
- The list is finished. Every item outside "Owner decisions" is
[x]or[-], and a discovery sweep found nothing new. - The build is blocked.
maincannot build, or the GPU lock or driver stays broken for 3 wake-ups in a row.
Before stopping, write a ## Loop summary to the tracker and commit it. It
lists:
- the acceptance gates, each with the old number, the new number, and pass or fail,
- the blocked items and why,
- the owner decisions with their measurements.