WIP: feat(runtime): HOS_COUNTERS, the memory and cache counters as one JSON line every N seconds #65
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
needs measurements
question
testing wanted
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!65
Loading…
Reference in a new issue
No description provided.
Delete branch "dyst/Longshot:feat/counters"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
To see whether memory leaks across a scene or a loop, today you collect lines from several places logged at different rates: the status line every 600 frames, the VMA heaps,
memory_stats, and the process's memory, which only the bug report shows. This writes them all side by side, one JSON line every N seconds, with a small reader.What changed
renderer:
counters_tickingpu/vk/vk_replay.cpp, called fromstatus_tick: withHOS_COUNTERS=<seconds>it writes one JSON line per interval toHOS_COUNTERS_FILE, elselongshot_counters.jsonlbeside the game. The first line names the format and the build,{"counters":1,"version":"...","every_s":5}. Each line has:vram_usage,system_heap_usage);memory_stats);draw_stats) and the program cache's hits so far (st_cache_hits,vk_progcache.h).Every counter is read where it is already kept, on the replay thread that owns the texture cache's. Unset, nothing is read or written.
interface:
MkwVkHost.host_countersingpu/vk/vk_api.h, the runtime's part of a line as JSON members;MKWVK_API_VERSION21 → 22.host:
host_countersinhost/rx_backend.c(the heap, its use, the regions,hos_process_memory's private memory and working set), last invk_host;hos_mem_regions()inhost/hos_mem.cgives the region count.renderer:
build_version()ingpu/vk/vk_menu.cpp(declared invk_menu.h) gives the version for the first line;system_heap_usageis declared invk_internal.h.scripts:
scripts/counters.py(new, standard library): a table;--diff [A B], line B against line A (by default the first and the last);--grew, the levels that went up at every line and never down, the leak check across a loop of the same scene. Counters "so far" (presents, draws, synced bytes...) are left out of--grew. A file of another format is refused.tests:
tests/test_counters.py(new).Not included: the virtual-core counters, whose stats reset every 5 s when logged and need a getter that doesn't reset them; and
HOS_MEM_MAP, which walks the whole address space and is too slow to sample.Flags and settings
HOS_COUNTERSHOS_COUNTERS_FILEHOS_COUNTERSwrites tolongshot_counters.jsonlbeside the game)Measurements
Run on a Longshot build of this branch (this PR was made on Longshot; there is no GitHub original). There is no main-side measurement:
mainhas noHOS_COUNTERS, and the run checks the counters' file, not a speed. The two columns are two points of the same run (counters.py --diff), not two builds.main:
82de567a(2026-11-12) (this branch's base; nothing was run on it)this PR: feat/counters @
03608e3aHardware: RTX 3080 (NVIDIA 621.14), Ryzen 9 3900X, 64 GB, Windows 11
Scene: from the start through a save into Kokiri Forest
Method:
HOS_COUNTERS=2, one launch;scripts/counters.py --difffrom the start to Kokiri Forest, and--grewHow to reproduce: set
HOS_COUNTERS=2, play from the start into Kokiri Forest from a save, thenpython -I scripts/counters.py --diffand--grewonlongshot_counters.jsonlcounters.py --diff--grew: only the mirrors went up at every line, as the scene loaded in.Testing
Tested: the runs under Measurements (on this branch) and the game-free checks this description names.
Not tested: Linux (the checks and the game run were on Windows only).
Needs other testers:
HOS_COUNTERS=2, expecting valid JSON lines with the process's memory read from /proc (request to open)Screenshots
Nothing on screen.
Risk and rollback
MkwVkHost.host_counters, version 22), so a renderer built before this change and a runtime built after it (or the other way round) no longer have the same version.counters_tickreturns after one cachedgetenv. Set, it writes and flushes a line on the replay thread every N seconds.HOS_COUNTERSunset turns it off; reverting the commit is enough.Reviewer notes
run_all.py): every check that reads the changed files (125), throughrun_all.py, Windows: 124 pass.test_readback_wait_boundedfails the same way on Longshot'smainon this PC.tests/test_counters.py:counters_tickis cut out and run against stub counters through a clock. Unset, it writes nothing and makes no file. Set to 5, its first line names the format, build and interval, then one line every 5 s (not one per present), each valid JSON with the runtime's members merged in.HOS_COUNTERS_FILE, and a runtime that gives no counters, also work.host_countersis cut out and run: its members, wrapped in braces, are JSON, and a buffer too small gives 0.counters.py: the table, the difference, what only grew, and a file of another format refused. In the source:status_tickcalls it;MkwVkHostends with the member, version 22; the runtime's table gives it last. Two deliberate breaks fail it: the "unset, nothing" line removed, and a line written at every present.Issues
None.
Checklist
For everyone
type(scope): description).main.python -I -B tests/run_all.pyrun and passing (any failure that also fails onmainis named above).third_party/untouched (a new folder with aPROVENANCE.mdinstead).If applicable
Assisted-by:/Co-Authored-By:trailers.docs/tested-configurations.mdfor each measured run.MKWVK_API_VERSIONbumped (gpu/vk/vk_api.h'sMkwVkHostorMkwVkRendererchanged).mainand passing here.tests/that reads changed source updated in this PR, not weakened.🤖 Generated with Claude Code
feat(runtime): HOS_COUNTERS, the memory and cache counters as one JSON line every N secondsto WIP: feat(runtime): HOS_COUNTERS, the memory and cache counters as one JSON line every N secondsBack to WIP under #48's process: this was carried over before the new template. Its description will be brought to the template and measured on Longshot (main against this PR, at named commits) when it's wanted for review; ask here if you'd like it sooner.
Description brought to Longshot's PR template (#48). Still WIP: it has a game run on this branch but no main-against-this-PR measurement yet, and it isn't rebased on current main.
Description moved to the template's Testing section and whole checklist (#72): what was tested, what wasn't, and what needs other testers (their test requests to open while this is WIP).
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.