Repository navigation
perf(kernel): the NV2A ack thread backs off when busy, off Windows - #113
Merged
Merged
Conversation
RECOMP_NV2A_ACK_BUSY_US defaults to 50 everywhere but Windows. It was off
because the titles that pace on the GPU fence had not been measured; on an
M4, alternated runs of 0 against 50:
OutRun 2 (fence-paced): 60 fps, same frame times capped and uncapped;
the thread 8% of a core -> 1.7%
TimeSplitters 2: 20-28% -> 2-3%, uncapped 119 -> 117 fps
Constantine: 25-35% -> 2%, uncapped 94 -> 92 fps
Nothing measurable at 60 in any of them. Windows keeps 0 until it has been
measured there; RECOMP_NV2A_ACK_BUSY_US=0 restores the old yield loop.
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.
The NV2A ack thread polls the GPU register words a title writes as plain memory. Nothing tells it when one changes, so while a title is busy it yields in a loop, which costs a fifth to a third of a host core for the whole run. That is power and thermal headroom the guest's own core needs on a laptop or a phone.
This turns on the busy backoff that was already there:
RECOMP_NV2A_ACK_BUSY_USnow defaults to 50 µs everywhere except Windows. After eight passes in a row that find nothing, the thread sleeps 50 µs between passes. Any change it finds puts it straight back to yielding.It was left off because nobody had measured the titles that pace on the GPU fence. OutRun 2 is one of them, and it shows no cost.
Measurements
Apple M4, macOS. Runs alternate between 0 and 50 so machine load lands on both sides equally. Each run was muted and in the background.
The only cost is 1.5–3% of the uncapped top end in TimeSplitters 2 and Constantine, from one run each per setting. Nothing is measurable at 60.
Scope
RECOMP_NV2A_ACK_BUSY_US=0restores the old loop on any host.RECOMP_NV2A_ACK_STATS=1prints the thread's CPU use and how often a change was found right after a sleep.