No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!728
Loading…
Reference in a new issue
No description provided.
Delete branch "build-speed-2"
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?
This combines three build-time changes into one branch, rebased on current main (
66892e6b, with #673 and the build timer). Each change is still its own commit(s), so each part can be reviewed and bisected separately. Supersedes #428, #429 and #561.What each part does
1. Lift: parallel output, and skipped when nothing it reads changed (was #428, 2 commits)
HOOKSHOT_LIFT_JOBS=<n>sets the process count (1 = the old single process). Where there is nofork(Windows), the lift stays one process.make_gameskips the lift (andsplit_hot) when its inputs match the last lift: the exefs,nx2/and the vendored a64-kit, the set of HLE functionshost/defines,hot_funcs.txt,chunks.txt, the lift'sA64_*/OOT_*/RX_*settings, and the Python version. Otherhost/code is not part of the key, so a rebuild after ahost/change no longer translates the game again.<work>/sa/gen/.lift_key.2. Compile order by cost (was #429, 2 commits)
code_NNN_k.cparts of about equal cost. The cost model: a function's compile time grows with roughly the square of its size. No other chunk boundary moves.gen/chunk_costs.txt, andbuild.pycompiles the longest files first, with hot pieces weighted ×4.split_hotdeals its call groups out to the 8 hot pieces by cost instead of bytes. The groups themselves, and so the inlining, are unchanged.3. Compilers started by the free memory (was #561, 1 commit, adapted to #673)
make_game, which picksfree / 2 GBonce, at the start. This branch keeps that change. On top of it,nx2/build.py'sMemoryGatestarts each compile only when the free memory, minus what the running compilers may still take, covers the file's estimated peak plusHOOKSHOT_MEM_RESERVE_GB(default 1.5).make_game's default becomes one compiler per CPU thread, and the gate decides how many actually run.tests/test_linux_builder_jobs.pyis updated for the new default: one per thread, and the floor is checked on the gate.--jobs. With one compiler per thread, it would otherwise promise too short a time.Turning each part off
HOOKSHOT_LIFT_JOBS=1<work>/sa/gen/.lift_key(the next build lifts)HOOKSHOT_MEM_GATE=0(thenHOOKSHOT_JOBS/--jobs/ one per thread, as before)HOOKSHOT_JOBS=<n>still caps it;HOOKSHOT_MEM_RESERVE_GB=<gb>keeps more memory freeMeasured
Setup: Linux, Ryzen 9 7900X (24 threads), 32 GB, other programs holding 12-19 GB. Each build is
make_gamewith the default job settings each side gives a user (noHOOKSHOT_JOBS), at nice 19 / SCHED_IDLE. The cold builds start from an empty work folder with the game already unpacked, with the hot list, play profile and chunk boundaries inwork/. Before and after builds ran one at a time, in alternation, on the same PC.Against main with #673 (
d09dacd8, just before the build timer; the timer only adds timing output):For a command-line build on this PC, #673 does not change the count: it chose 9 compilers here, the same as main before it. Its gain is in the Linux builder window, which chose fewer before. So the whole 37% here comes on top of #673.
Against the main before #673 (
5a5c7e65), same setup: cold builds took 671 s and 730 s on main, 461 s on this branch (−31% / −37%).Rebuilds (an earlier run on the older main without the play profile in
work/; repeat runs on current main will follow):host/*.cfile changedMore runs will be added here: a second cold pair, warm and one-
host/-file rebuilds on current main,HOOKSHOT_JOBS=6on both sides, and an in-game fps check.In game: an earlier build of this combination (on the older main, both sides built without the play profile) reached play with normal draw counts, at the same fps as main's build (55.1 vs 54.2 fps over 40 s, with no flicker events).
Tests
66892e6b. A short build (the lift and the first objects) gives the timer's@@plan/@@eta/@@filelines, and the compile runs longest first.tests/test_parallel_emit.py,tests/test_lift_cache.py,tests/test_chunk_split.pyandtests/test_mem_gate.pyall pass.tests/test_linux_builder_jobs.py(updated),tests/test_build_times.pyandtests/test_builder_status.pypass.tests/test_*.pyon main and on this branch. The same two fail on both, and neither is about this change:test_cpp_preflight.pyneeds--cxx, which CI passes.test_make_game_cache.pyfails only locally: a clang probe in its fixture.source-regressions.ymlyet. Each one runs aspython -I -B tests/<name>.pyif you want to add them.Thanks!