Fire Emblem: Three Houses: record why its two pacing cuts stay per-build. Checked on the Mac (host at 7753b7b, headless boot to the title, 100 s per run, each cut undone in the rewritten main): without the frame-limiter cut the general yield back-off holds 59.7-59.8 fps (frame p50 16.73 ms against 16.68) at 0.9-1.2 W of CPU energy against 0.14-0.42 W (about 9,700 plain yields a frame before the back-off starts at 2 ms); without the render-thread timeout cut, 53,000-55,000 wakeups a second against 1,450 and 0.7-1.0 W. The 16 us timeout is the game's own: the render thread passes (1/fps) x 1000 = 16 to main+0xaa90e0, which multiplies it by 1000 into the TimeSpan (nanoseconds) of nn::os::TimedWaitEvent. Of the 206 modules on hand, the limiter (main+0x5be4b4) is the only loop whose only calls are YieldThread and GetSystemTick, so a rewriter pass for such loops would match this one site. Docs: the game note; docs tests pass
This commit is contained in:
1 parent
dac7ba6338
commit
f171088e2e
1 file changed
+1
@@ -22,6 +22,7 @@ Update 1.2.0 (v327680) over the base game, SDK 6.5.0. Koei Tecmo's older KTGL en
|
||||
- **Current:** the render thread also forced interval 2 while either of two flags was set: `main+0x21c9a03`, a full-screen image drawn before the frame (`main+0x4b4908`: the opening movie), and frame +0xc55f / +0xc560 (from the object at app +0x40: the character creation screen after the movie, and so on). In the engine's own 60 fps modes this traded 60 fps for resolution in those scenes (`main+0x50f7d0` drops 720p mode 1 to 1080p mode 0). A cut at `main+0x50fb7c` (`orr w8,w9,w8` → `mov w8,wzr`) ignores both, so those scenes run at 60 too; the movie still lasts 210.6 s (6,318 frames at 30 fps), as in the original.
|
||||
- **Current:** the frame limiter (`main+0x5be430`: yield, read the tick, until the target has passed; x8 = time passed and x23 = target, in 100 ns) yielded and polled the clock, which on the host spun its first 2 ms on a performance core and then overslept by up to 250 µs: frames took 16.8 ms (59.5 fps, a repeated display frame every 2 s) and CPU energy went from 0.16 W at 30 fps to 1.5 W on the Mac (228,000 yields a frame on an iPhone). The yield becomes `nn::os::SleepThread` of 96% of the time left (PLT `main+0xafc300`), and the loop goes back to the limiter's own tick read at `main+0x5be44c`; the frames take 16.68 ms.
|
||||
- **Current:** the render thread waits for the next update with KTGL's event wait (`main+0xaa90e0`, timeout in µs: × 1000 → `nn::os::TimedWaitEvent`) and passed 1/fps × 1000 = 16, one frame in ms, so it polled every 16 µs (42,000–53,000 wakeups a second on the Mac at 60 fps, against 1,200 at 30 fps, where it waited in the present instead). The timeout becomes 1000/fps × 1000 = 16,666 µs. The other four callers wait without a timeout.
|
||||
- **Current: both pacing cuts stay per-build, and neither stands in for a host fault** (checked 2026-10-26, host at `7753b7b`, headless boot to the title on the Mac, 100 s per run, each cut undone in the rewritten `main`). Without the limiter cut the general yield back-off (`thr_yield`) holds 59.7–59.8 fps (frame p50 16.73 ms against 16.68) at 0.9–1.2 W of CPU energy against 0.14–0.42 W: about 9,700 plain yields a frame before the back-off starts at 2 ms. Without the timeout cut: 53,000–55,000 wakeups a second against 1,450, and 0.7–1.0 W. The 16 µs is the game's own: the render thread passes (1/fps) × 1000 = 16 to `main+0xaa90e0`, which multiplies it by 1000 into the `TimeSpan` (nanoseconds) of `nn::os::TimedWaitEvent`, so a frame in milliseconds goes where microseconds are taken. Only a wait that knows its deadline can sleep until it, and only the game's code holds it: of the 206 modules on hand, the limiter (`main+0x5be4b4`) is the only loop whose only calls are `YieldThread` and `GetSystemTick`, so a rewriter pass for such loops would match this one site.
|
||||
- Prologue battle on the Mac with the cuts: 59.9 fps, 55% of a core and 1.8 W of CPU energy (the original at 30 fps: 44% and 1.7 W).
|
||||
- Before the limiter cut, the host's yield back-off alone took its CPU time on the Mac from 78% to 19% of a core, same frame times ([development.md, Power](../../../docs/development.md#power)).
|
||||
|
||||
|
||||
Reference in new issue
Block a user