Repository navigation
Opt-in pacing switches for the iPhone judder: DM_PCORE, DM_RT60, DM_ITV_LATCH (not fully tested) - #1713
Closed
oliverames wants to merge 3 commits into
Closed
Opt-in pacing switches for the iPhone judder: DM_PCORE, DM_RT60, DM_ITV_LATCH (not fully tested)#1713oliverames wants to merge 3 commits into
oliverames wants to merge 3 commits into
Conversation
This was referenced Nov 7, 2026
Contributor
Author
|
Rebased onto main 7f50222: one conflict in hle_nvn.c (kept main's window_interval and its comment, kept the latch inside present_itv). Tests: t_nvn 248 checks 0 failed, t_gfx_suspend 22 checks 0 failed, test_docs 11 OK; env_switches --check flags only main's DM_NVN_BC_ALIAS and DM_YIELD_CLOCK, none of ours. |
oliverames
force-pushed
the
mkw-pacing-optins
branch
2 times, most recently
from
November 10, 2026 00:52
2e80b49 to
f3e143b
Compare
2 of 3 tasks
oliverames
force-pushed
the
mkw-pacing-optins
branch
from
November 10, 2026 12:31
f3e143b to
4e8618d
Compare
oliverames
pushed a commit
to oliverames/nxnative
that referenced
this pull request
Nov 10, 2026
…me on an iPhone, and the phone restarts some minutes later (Mario Kart World 1.8.0, iOS 27.3 beta); open On an iPhone 19,4 the picture stopped 2 to 3 s into a race, 184 s after launch, with the overlay at 0 fps, the process alive, no [RED] line and no GPU error. Every thread waited and none spun. The state dump has the replay thread in iokit_user_client_trap under res_commit (pool_res, with g_mu held by its caller and g_res_mu across the call) and the GPU's completion queue waiting for a mutex in post_complete, with the main fence at submitted 206262 / completed 206256. Ending the app did not end the process. The system's stack report 15 minutes later still has it with one thread, NVN queue replay, in an uninterruptible kernel wait with a read-write lock held and a kernel thread blocked on it, and the phone at 7.2 GB wired and 34 MB free. The phone then restarted itself. It happened twice in four runs of one build (main 04811a6 with PRs seedds#1709, seedds#1695, seedds#1262, seedds#1599 and seedds#1713 merged): in that race, and an hour later at the title's demo with no button pressed, 353 s after launch, with the same thread state. Both came in a scene load (1,840 allocations added to the residency set in 678 commits in the 300 frames before the second). With main's 6f50de0 and 12a44e0 added, four races did not freeze, which is too few to say it is gone. The game makes about five residency commits a frame in a race. No fix: the entry says what was ruled out, what the host could change, and what to collect from the phone (SIGALRM for the host's dump, then systemCrashLogs). The game note links it under Open.
added 3 commits
November 10, 2026 09:00
…declaration, to keep them on the performance cores Off by default and not yet shown to help: a Mario Kart World run on an iPhone left the performance cores about a minute in with thermal state nominal (mean clock 3.8 to 1.65 GHz, 55% to 12% of CPU time on performance cores). iOS has no core affinity; a time-constraint declaration is what the scheduler places on a fast core. The three busiest guest threads without one get a 60 Hz declaration of 1.5x their measured per-frame CPU, once each, from the CPU sampler's window.
…riod when the game flips its present interval Off by default. On Mario Kart World 1.8.0 on an iPhone 19,4 it made no visible difference to the slowdown (2026-11-07). Mario Kart World on an iPhone flips its present interval 1 and 2 about 350 times in 20 s after a late frame, re-declaring 16.7 / 33.3 ms to the scheduler each time, and around those flips the process left the performance cores (mean clock 3.5 to 1.6 GHz, thermal fair).
…lates between 1 and 2 Off by default. On Mario Kart World 1.8.0 on an iPhone 19,4 it cut the interval flips (12 against 58 in comparable stretches) and did not change the GPU's slowdown (2026-11-07). Mario Kart World on an iPhone flips its present interval about 350 times in 20 s after a late frame, which shows the screen at alternating 16.7 / 33.3 ms periods. The latch holds interval 2 until the game has asked for 1 for DM_ITV_LATCH_MS (3000), so the screen runs one steady 30 fps.
oliverames
force-pushed
the
mkw-pacing-optins
branch
from
November 10, 2026 14:04
4e8618d to
5da0a12
Compare
Contributor
Author
|
Closing this. Since main's 6815810, Mario Kart World 1.8.0 runs under the host's frame step, and as this PR's description says, |
oliverames
pushed a commit
to oliverames/nxnative
that referenced
this pull request
Nov 12, 2026
…1.8.0 (6815810), and seedds#1713 is closed
2 of 3 tasks
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
Three opt-in pacing switches for the iPhone judder after about 30 to 70 s of a Mario Kart World 1.8.0 race, in one PR because they touch the same scheduler and present code and are tried together. Nothing changes unless a switch is set.
DM_PCORE=1: the busiest guest threads get a time-constraint declaration, to keep them on the Performance cores.DM_RT60=1: the scheduler declaration keeps the base vsync period when the game flips its present interval.DM_ITV_LATCH=1: hold present interval 2 while the game oscillates between 1 and 2.Not fully tested. On Mario Kart World 1.8.0 on an iPhone19,4 (2026-11-07),
DM_RT60=1made no visible difference to the slowdown,DM_ITV_LATCH=1cut the interval flips (12 against 58 in comparable stretches) and didn't change the GPU's slowdown, andDM_PCORE=1's effect isn't measured. On a build with the host's frame step (the base game since main7d8dcdf82)DM_ITV_LATCHandDM_RT60do nothing, becausepresent_itvreturns the step andrt_period_nskeeps the cap's deadline. So they are here as opt-in knobs, not as a fix. Replaces #1699, #1700 and #1701.Checked
dm/tools/env_switches.py --checkshows no problem for the three new switches (the check exits 0 on this branch, rebased onto mainab41d6a17on 2026-11-10)python3 dm/tools/tests/test_docs.pypassesscripts/regress.py check --gamesFront ends
No front-end interface change.
Docs
docs/env_switches.tsvrows for all three;docs/development.mdnotes.