From fed7aca7fc2f251d92ac9b648064da4f12a7b940 Mon Sep 17 00:00:00 2001 From: chrg6 Date: Sat, 14 Nov 2026 05:18:15 -0500 Subject: [PATCH] Leave Helpers work ahead and Helpers take small jobs off by default, as in 0.10.1. 0.10.2 was to turn replay_pipe = 4 and replay_small = 16 on by default. A tester measured those two with five replay workers against the defaults on an RTX 3090, standing at eight places in Hyrule Field and at Lake Hylia with the default run repeated (within 3 %): slower at four of them (50.1 instead of 58.1 fps at one) and level or at most 7 % faster at the other four. The user decided to leave both at 0. CPU helper threads stay Automatic and Start next frame early stays on, as 0.10.1 shipped them; the notes and nx2navi.ini.example say so. Co-Authored-By: Claude Fable 5.2 --- docs/releases/v0.10.2.md | 14 ++++---------- nx2navi.ini.example | 14 ++++++++------ runtime/cfg.c | 4 ++-- runtime/vk_exec.c | 4 ++-- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/docs/releases/v0.10.2.md b/docs/releases/v0.10.2.md index 28f014eb..79f13975 100644 --- a/docs/releases/v0.10.2.md +++ b/docs/releases/v0.10.2.md @@ -14,16 +14,10 @@ cards). ## Changed -- **The Game tab's Testing settings are on by default:** - - *CPU helper threads*: Automatic (`replay_workers = auto`): half the CPU's cores less one, none on four cores or - fewer and none on AMD's driver for Radeon RX 6000 and older; - - *Helpers work ahead*: 4 (`replay_pipe = 4`); - - *Helpers take small jobs*: 16 (`replay_small = 16`); - - *Start next frame early*: On (`tail_early = 1`). - - The first and the last were already so in 0.10.1; the two in the middle are new. They are still experimental. A - value you chose yourself, in the settings menu or in nx2navi.ini, stays as you set it: to keep 0.10.1's behaviour, - set *Helpers work ahead* and *Helpers take small jobs* back to 0. +- **The Game tab's Testing settings keep 0.10.1's defaults:** *CPU helper threads* Automatic + (`replay_workers = auto`), *Start next frame early* On (`tail_early = 1`), and *Helpers work ahead* and *Helpers + take small jobs* off (`replay_pipe = 0`, `replay_small = 0`). The last two stay experimental: a tester's + measurement on an RTX 3090 found them slower at four of eight places and no more than 7 % faster at the others. - **Automatic texture detail is more careful with video memory** (`texture_detail = auto`): *Full* now starts at cards of 12 GB (10 GB cards get *Reduced*, as 8 GB cards do), and integrated graphics never get *Full*, because their video memory is the PC's own memory. With a card filled to the room of an 8 GB one, a tester measured 29.6 fps diff --git a/nx2navi.ini.example b/nx2navi.ini.example index a8850292..66cd207f 100644 --- a/nx2navi.ini.example +++ b/nx2navi.ini.example @@ -119,14 +119,16 @@ # Does nothing without one of those upscalers, nor with the lazy write-back (the default on NVIDIA and Intel cards). # Also in the menu: Game, Testing, Start next frame early. # tail_early = 1 -# EXPERIMENTAL, with replay_workers. replay_pipe = N (0 to 4, default 4): the submitting thread goes on past up to N -# groups its workers still record. replay_small = N (0 to 63, default 16, needs replay_pipe): a group of N draws or more +# EXPERIMENTAL, with replay_workers. replay_pipe = N (0 to 4, default 0): the submitting thread goes on past up to N +# groups its workers still record. replay_small = N (0 to 63, default 0, needs replay_pipe): a group of N draws or more # that is too small to share out (fewer than 64 draws) goes whole to one worker; 64 or more reads as 63. Kokiri Forest # standing on an RX 7900 XT with FSR 4, tail_early = 1, replay_workers = 5, replay_pipe = 4 and replay_small = 16: 63 -# instead of 45 fps with all of them off. Also in the menu: Game, Testing, Helpers work ahead (replay_pipe) and Helpers -# take small jobs (replay_small). Neither does anything without replay workers. -# replay_pipe = 4 -# replay_small = 16 +# instead of 45 fps with all of them off. On an RTX 3090 a tester measured the same three settings against the +# defaults at eight places: slower at four (50.1 instead of 58.1 fps at one) and level or up to 7 % faster at the +# other four. So both stay off unless you turn them on. Also in the menu: Game, Testing, Helpers work ahead +# (replay_pipe) and Helpers take small jobs (replay_small). Neither does anything without replay workers. +# replay_pipe = 0 +# replay_small = 0 # EXPERIMENTAL, THE GAME CRASHES WITH 1. 1 lifts the virtual core gate: guest threads run without the console's limit # of one thread per core, and the game keeps per-core data without locks. With 1 the game crashes or hangs, # usually at start. Keep 0 to play. diff --git a/runtime/cfg.c b/runtime/cfg.c index 515e9318..07c7e0c0 100644 --- a/runtime/cfg.c +++ b/runtime/cfg.c @@ -328,11 +328,11 @@ static const CfgMeta metas[] = { {"DISCORD_IMAGE", NX2NAVI_DISCORD_IMAGE_DEFAULT, NULL, LIVE}, // Advanced: scheduling {"ASYNC_PREEMPT", "1", "0|1|2", RESTART}, {"REPLAY_ASYNC", "0", "0|1", RESTART}, - {"REPLAY_PIPE", "4", "0..4", RESTART}, + {"REPLAY_PIPE", "0", "0..4", RESTART}, {"REPLAY_WORKERS", "auto", "auto|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16", RESTART}, // vk_exec.c rw_init, vk_exec_replay_workers_auto // vk_exec.c "the early tail"; on by default since 0.10.0 {"TAIL_EARLY", "1", "0|1", RESTART}, - {"REPLAY_SMALL", "16", "0..63", RESTART}, // vk_exec.c group_start + {"REPLAY_SMALL", "0", "0..63", RESTART}, // vk_exec.c group_start {"FREE_CORES", "0", "0|1", RESTART}, {"TIMER_1MS", "1", "0|1", RESTART}, // dynamic resolution (dynres.c): the scene follows the GPU time toward DYN_RES_TARGET milliseconds (under 1: the // frame limit's frame time), holding each step DYN_RES_STEP 60 Hz frames of the clock diff --git a/runtime/vk_exec.c b/runtime/vk_exec.c index b032517c..6ee1cab0 100644 --- a/runtime/vk_exec.c +++ b/runtime/vk_exec.c @@ -1923,7 +1923,7 @@ static void op_one(VkExec *ex, const op_hdr *h) { // replays the op again once in turn, and so do the contact shadows' pass and the HDR pass's source. Per-object motion // lists its draws under a lock (vk_exec_draw.c mvobj_draw), and the occlusion queries' slots and segments follow the // stream (vk_exec_xfer.c vk_exec_xfer_slots, vk_exec_xfer_group_merge). -// NX2NAVI_REPLAY_PIPE=N (0-4, default 4): the submitting thread hands the group to the workers, takes chunks of it as +// NX2NAVI_REPLAY_PIPE=N (1-4, default 0): the submitting thread hands the group to the workers, takes chunks of it as // they do until none is left to take, and goes on with the ops after it, in a new command buffer after the chunks' // places in the part (vk_sync_append_later), while the last chunks are recorded; also into the front pass of the next // group: up to N (at most LIVE_GROUPS) groups are handed out and not in their part yet, their chunks taken from one @@ -2472,7 +2472,7 @@ static const op_hdr *group_start(VkExec *ex, const op_hdr *h, int depth) { int n = (int)(draws / CHUNK_DRAWS); if (n > RW.n + 1) n = RW.n + 1; if (n > GROUP_CHUNKS) n = GROUP_CHUNKS; - // NX2NAVI_REPLAY_SMALL=N (default 16, with NX2NAVI_REPLAY_PIPE): a group of N draws or more that is too small to cut + // NX2NAVI_REPLAY_SMALL=N (default 0, with NX2NAVI_REPLAY_PIPE): a group of N draws or more that is too small to cut // goes whole to one worker, and the submitting thread goes on with what follows it without taking the chunk // itself. Kokiri Forest standing, 5 workers, 4 groups out, the early tail on (2026-11-13): about 700 draws a frame // were in such groups, 3.6 ms of the submitting thread; with 16 the replay took 10.2 instead of 11.0 ms a frame