Repository navigation
Keep automatic frame CPU budgets per frame and per thread - #2137
Closed
thehobbit85 wants to merge 1 commit into
Closed
thehobbit85 wants to merge 1 commit into
thehobbit85 wants to merge 1 commit into
Conversation
seedds
added a commit
that referenced
this pull request
Nov 13, 2026
The acquire thread's time-constraint record was registered once, on the first thread that acquired, with that thread's port. A game that acquires from another thread had its CPU time subtracted from the first thread's samples and its declaration set on the first thread's port. Each thread that acquires now has its own slot (rt_acquire). An acquire thread that has not acquired for a window of 120 frames goes back to the standard policy (rt_retire, only while its port still names that thread), and declares at once what it had if it acquires again. The thread policy line reads the declarations atomically. OCTOPATH TRAVELER II acquires from two threads: its first is retired after its first frames. t_rt_comp (from PR #2137, run in its auto, fixed and off modes, now in CI with t_thread_rt) drives the acquire path: a frame acquired in two calls declares its whole 6 ms as 7.5 ms, a second thread learns its own 1.25 ms, and an ended thread is retired with no call on its port. Mac regression check: Mario Kart World and OCTOPATH TRAVELER II pass. Octopath had GPU stalls (one command buffer 120-160 ms) in 2 of 9 runs with the frame threads declaring, within half an hour of each other, and in none of the next 7 nor of 18 runs without; whether the declarations play a part is recorded as open in docs/reference/frame-rate.md. Co-authored-by: Eliran Zach <4012041+thehobbit85@users.noreply.github.com>
Owner
|
Thank you: the diagnosis holds and is on main in b06f4e0 (you are credited as co-author), on top of PR #2569 (4c71083), which rewrote this code. Sampling once per presented frame came with #2569. The per-thread part is now a slot per acquiring thread, so each thread's CPU clock and policy are its own, and a thread that stops acquiring for 120 frames goes back to the standard policy. Your acquire-path test is in as dm/gfx/tests/t_rt_comp.c, adapted to the new code: it runs its auto, fixed and off modes in one call and is in CI's CPU-only list. Whether this played a part in #1985's Castle Town slowdown is still open, so that issue stays open. |
iDams
pushed a commit
to iDams/nxnative
that referenced
this pull request
Nov 13, 2026
…dds#2137) The acquire thread's time-constraint record was registered once, on the first thread that acquired, with that thread's port. A game that acquires from another thread had its CPU time subtracted from the first thread's samples and its declaration set on the first thread's port. Each thread that acquires now has its own slot (rt_acquire). An acquire thread that has not acquired for a window of 120 frames goes back to the standard policy (rt_retire, only while its port still names that thread), and declares at once what it had if it acquires again. The thread policy line reads the declarations atomically. OCTOPATH TRAVELER II acquires from two threads: its first is retired after its first frames. t_rt_comp (from PR seedds#2137, run in its auto, fixed and off modes, now in CI with t_thread_rt) drives the acquire path: a frame acquired in two calls declares its whole 6 ms as 7.5 ms, a second thread learns its own 1.25 ms, and an ended thread is retired with no call on its port. Mac regression check: Mario Kart World and OCTOPATH TRAVELER II pass. Octopath had GPU stalls (one command buffer 120-160 ms) in 2 of 9 runs with the frame threads declaring, within half an hour of each other, and in none of the next 7 nor of 18 runs without; whether the declarations play a part is recorded as open in docs/reference/frame-rate.md. Co-authored-by: Eliran Zach <4012041+thehobbit85@users.noreply.github.com>
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.
What and why
The automatic real-time CPU budget was measured on every texture acquire, so multiple acquires split a frame's CPU work and underdeclared its budget. Global sampling and policy state also mixed different threads' CPU clocks: a replacement acquire thread could skip its initial policy and subtract another thread's clock.
Sample the first acquire after a present and keep the CPU samples, declared budget and policy period per thread. Preserve the existing estimation window, margins, cap, fixed-budget mode and disabled mode. A synthetic test exercises the real acquire path while replacing only the operating-system CPU clock and policy submission; CI runs its automatic, fixed and disabled modes without a GPU.
Related to #1985. These are reproduced scheduling defects; whether either explains OoT's Castle Town slowdown remains unverified. Finding: budgets sampled per acquire or across threads, linked from the OoT note.
Checked
make -j4 -C dm/gfx/tests GAME=0400486024DEC000 run— passed.make -C dm/gfx/tests GAME=010015100B514000 -W t_rt_comp.c check_t_rt_compalso passed with CI's Wonder profile.python3 -m unittest discover -s dm/tools/tests— final run: 1,435 tests; 1,411 passed, 23 skipped, one inherited failure. The inherited ABI-literal-ratchet failure in unchangednvn_mtl.malso reproduces from pristine base revision976fbd57f5cbee1f374453c2450c92ffd9f20dbc.test_triage_report.Report.test_main_loadstdout assertion; it passed both alone and in the full rerun.git diff --checkpassed.scripts/regress.py impact BASE..HEADwas run. Usage coverage is unknown; no gameplay regression run was possible without game files. Intended checks: OoT (0400486024DEC000, reported scheduling slowdown), Pokopia (0400A3A01EE4C000, NVN2), Monster Hunter Rise (0100B04011742000, engine frame limiter), Fire Emblem Engage (0100A6301214E000, Unity), and Super Mario Bros. Wonder (010015100B514000, Nintendo NVN). None is claimed gameplay-validated by this PR.Docs