Idea: ship play profiles (the hot list and the renderer's profile) with releases #505
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
beanstalk: approved @ 1697603
beanstalk: approved @ 2c5a62e
beanstalk: approved @ 4fd82b7
beanstalk: approved @ 64d6d09
beanstalk: approved @ 6f91fae
beanstalk: approved @ 70a78f9
beanstalk: approved @ 8d361dc
beanstalk: approved @ 9d8356e
beanstalk: approved @ abf2227
beanstalk: approved @ d82f202
beanstalk: approved @ e5f1e40
beanstalk: approved @ ee8ab5f
ci: approved
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/macos
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
regression
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
ci: approved
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot#505
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
The idea
Longshot already has everything needed to build the hottest lifted game functions at
-O2with a play profile, but releases don't ship with it, so every player's build compiles all of the lifted code at-O1.What exists today
scripts/hotlist.pyturns a sampled play session (HOS_SAMPLE_ALL) intohot_funcs.txt: the lifted functions that make up the first 85 % of samples, hottest first, capped at 1,500, plus the game's Zstd decoder.nx2/split_hot.pyputs those functions into eight hot pieces compiled at-O2with the play profile (RX_PGO, fitted to the pieces bynx2/pgo_pieces.py).scripts/tools.py assemble profilepacks the list and the profile for a release (RELEASING.md).make_game.pyuses them whenwork/has them.tools.lockhas noprofileline ("No play profile yet").What it buys and what it costs
With today's list, the 85 % cut comes to about 850 functions (849). Measured against main
0caf0618, the whole build before shaders:The proposal: generate the list before each release and ship it
hotlist.py <run> <out> 1.0 300) keeps the build cost the same from one release to the next; a share gives a different count on every session.tools.py assemble profile,tools.py add, and theprofileline intools.lock.The renderer's play profile
The renderer (our own Vulkan code,
gpu/vk/) can be built with a play profile of its own, and that helps more than the hot list does, at almost no build cost.What it is: a counting build of the renderer (
RX_VK_PGO=gen), a session played with it, then the renderer built with the counts (RX_VK_PGO=<file>). It's ported from ProjectReLink, on the local branchbuild/vk-pgo, not pushed yet. The renderer needs no hot list: it's small enough to build whole with the profile.What it buys: on a Ryzen 9 7900X with an RTX 3090, from the Market save, main against main with the renderer built with the profile. Median frame:
That's about -4 to -5 % standing and -3 % running. -O3 and link-time optimisation added nothing on top in a first screening.
What it costs: almost no build time. Players already compile the renderer (about a minute of one compile job), and the profile only changes how. No prebuilt renderer is needed: the release ships the profile file and the builder uses it.
Still to settle:
Both profiles would ship the same way: in the play profile bundle (
tools.py assemble profile) and theprofileline intools.lock.Related
Anything else
The play profile holds addresses and counts only, no game data; the owner has approved publishing it. Measurements and scripts are on the PC that made them, and they can be added here.
🤖 Generated with Claude Code
Idea: ship hot lists with releasesto Idea: ship play profiles (the hot list and the renderer's profile) with releasesA data point on what the hot list and the play profiles buy, from a player's own build on Windows. Short version: on a Ryzen 5 5600X a hot list and profiles recorded on this PC changed nothing I can measure against an old list and a stale profile, because here the frame is paced by hand-offs between the game's threads, not by how fast the lifted code runs. I did not measure against no hot list at all, which is what a release ships.
Setup. Main
6c9edffewithea6dc5f5cherry-picked, llvm-mingw clang 23.1.5,-march=native(znver3). Ryzen 5 5600X (6 cores, 12 logical processors), 24 GB, RX 5600 XT 6 GB (the compute fallback), Windows 11. Render resolution 50% of 1920x1080, Threaded rendering Auto (on),RX_VK_LOAD=create,RX_VK_MIRROR_SPARSE=0,RX_VK_WB_MAX_KB=1024. Standing after a teleport, 25 s after 10 s, the builds interleaved. Kokiri Forest (800 draws) and Hyrule Field (1,230 draws) are the two areas where the GPU's frame (12.0-12.7 ms) is well under the frame time, so the CPU side sets the frame rate there.HOS_SAMPLE_ALLwalk through twelve areas, 8 minutes); C's, fromscripts/hotlist.py <file> <out> 0.92 1500, covers 92%, with 867 functions A's does not have. The heaviest functions outside A's list are the game's Zstd decoder (f_801102e05.5%,f_801108601.1%: the walk loads an area every 35 s) andf_8372a5a0(3.0%).RX_PGO=gen RX_VK_PGO=gen, counters cleared after the load and written before the exit, one walk through the same twelve areas. The renderer's recording works on Windows (assets/profiles/README.mdlists a Windows recording as not done yet): the submit is about 5% shorter in B than in A, the only difference above that I would call real.scripts/cpu_report.pyon the sampled run (with--readobj): lifted game code 165% of a core, the renderer 97%, the host 56%; no thread is saturated.sead::MainThreadruns 28.1% of the time and waits 42.2% innn::os::WaitLightEvent(its job workers), 14.5% in the renderer'swaitand 7.6% innn::os::SleepThread; eachBaseProcExecutorruns 15%,mkw_vk_replay44.7%. Its reading: "the frame is most likely paced by the chain of hand-offs between threads".HOS_VCORES=0,HOS_RESERVE_CORE=0,HOS_VCORE_SLICE_US=500,HOS_SHORT_SLEEP_POLLERS=1,HOS_SHORT_SLEEP_TIMER=1,HOS_SPIN_US=0,RX_VK_RECORDER_PIN=sibling,RX_VK_PRESENTS_AHEAD=2(Kokiri Forest 57-62 fps in all of them).Not measured: no hot list at all (every lifted file at
-O1), which is the comparison this issue is about; a walk or a fight rather than standing; load times, where the Zstd decoder's 6.6% says a current list could matter more than in the frame rate; a CPU with fewer cores, where the lifted code may be the limit.