Repository navigation
perf(agc): import a range mapped again on first use instead of at map - #8622
adriadam10 merged 1 commit into
Conversation
|
This pull request is labeled |
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
| std::map<std::uint64_t, ImportFailure> failedJoins; | ||
| std::map<std::uint64_t, std::uint64_t> sparseRunEnds; | ||
| std::map<std::uint64_t, std::uint32_t> sparseRunJoins; | ||
| std::set<std::uint64_t> importedAtMap; |
There was a problem hiding this comment.
importedAtMap is a process-lifetime history: this inserts every distinct mapped range address, and the only clear in the diff is on device change. A workload that repeatedly maps fresh addresses and unmaps them can leave one std::set node per address after the corresponding imports are gone. Could this history be bounded (for example, evict older addresses at a fixed cap)? If an evicted address is seen again, eagerly importing it is the existing behavior, so the cap should affect only this optimization, not correctness.
|
These are the traces behind the two summary lines in the description. Both are SuperTuxKart main-menu captures with
The import and the retirement this PR moves run on the title thread, which is untraced (143 ms of the frame). That is why the digests show the change in frame time and presents, not in a named slice: 56 → 67 presents in 8.1 s, p50 144.2 → 120.8 ms.
|
| thread | busy | wait | untraced | in slices < 20 us | largest |
|---|---|---|---|---|---|
| title | 1.5 (1 %) | 0.0 (0 %) | 143.1 | 0.0 | Recorder.Sync 1.5 |
| queue worker 0x0 | 2.9 (2 %) | 140.5 (97 %) | 1.2 | 4.1 | Driver.Packet 2.9, Driver.Completion 0.0 |
| draw committer | 23.2 (16 %) | 0.3 (0 %) | 121.2 | 0.1 | Graphics.Draw 10.2, Vulkan.DrawFromRecipe 9.0 |
| presenter | 0.9 (1 %) | 1.0 (1 %) | 142.8 | 0.0 | VideoOut.Flip 1.8, Driver.Present 0.0 |
| gpu | 1.6 (1 %) | 0.0 (0 %) | 143.0 | 0.0 | batch 1.6 |
Largest slices (ms per frame, inclusive, all threads): Driver.WorkerWait 140.5, Driver.WorkerWait.idle_and_completion_poll 140.4, Graphics.Draw 10.2, Vulkan.DrawFromRecipe 9.0, Graphics.DrawWithRecipe 9.0
Longest waits
- Driver.WorkerWait (queue worker 0x0) 6.2 ms at 4251 ms, present 249
- Driver.WorkerWait (queue worker 0x0) 5.4 ms at 6434 ms, present 264
- Driver.WorkerWait (queue worker 0x0) 5.2 ms at 7018 ms, present 268
- Driver.WorkerWait (queue worker 0x0) 5.1 ms at 6463 ms, present 264
- Driver.WorkerWait (queue worker 0x0) 5.1 ms at 3424 ms, present 243
Largest GPU batches (GPU ranges inside, and the CPU slices that recorded each, inclusive)
- batch 2874: 2.1 ms at 1135 ms, present 227: GPU no ranges; recorded by Vulkan.DrawFromRecipe (draw committer) 0.1, Graphics.DrawWithRecipe (draw committer) 0.1, Graphics.DrawWithRecipe.draw_and_resource_release (draw committer) 0.1, Recorder.Submit (draw committer) 0.1
- batch 3063: 2.1 ms at 1601 ms, present 231: GPU no ranges; recorded by Vulkan.DrawFromRecipe (draw committer) 0.3, Graphics.DrawWithRecipe (draw committer) 0.3, Graphics.DrawWithRecipe.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.1
- batch 2635: 2.1 ms at 551 ms, present 223: GPU no ranges; recorded by Vulkan.DrawFromRecipe (draw committer) 0.1, Graphics.DrawWithRecipe (draw committer) 0.1, Graphics.DrawWithRecipe.draw_and_resource_release (draw committer) 0.1, Recorder.Reap (draw committer) 0.0
- batch 3183: 2.1 ms at 1888 ms, present 233: GPU no ranges; recorded by Vulkan.DrawFromRecipe (draw committer) 0.2, Graphics.DrawWithRecipe (draw committer) 0.2, Graphics.DrawWithRecipe.draw_and_resource_release (draw committer) 0.2, Recorder.Submit (draw committer) 0.0
- batch 3003: 2.1 ms at 1454 ms, present 230: GPU no ranges; recorded by Vulkan.DrawFromRecipe (draw committer) 0.3, Graphics.DrawWithRecipe (draw committer) 0.3, Graphics.DrawWithRecipe.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.1
tools/trace_digest.py with this PR
seconds 40:8 from present 262: 67 presents, frame p50 120.8 / p90 126.9 / p99 134.2 / max 134.2 ms, GPU busy 6.0 ms per present
AMD Radeon(TM) 860M Graphics, AMD proprietary driver 24.30.58.08 (LLPC), Windows 10.0.26300, 1920x1080, commit 976583da31c3, dropped: no
{"commit":"976583da31c3","dirty":false,"env":{"APS5_NO_PAD_INPUT":"1","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"40:8"},"gpu":"AMD Radeon(TM) 860M Graphics","driver":"AMD proprietary driver 24.30.58.08 (LLPC)","os":"Windows 10.0.26300","cpu":"AMD Ryzen AI 7 350 w/ Radeon 860M","cpu_threads":16,"memory_mib":31866,"title_id":"PPSA69421","title":"SuperTuxKart","content_version":"00.001.000","resolution":"1920x1080","window":{"spec":"seconds 40:8","first_present":262,"ms":8076.091},"presents":67,"frame_ms":{"p50":120.842,"p90":126.906,"p99":134.245,"max":134.245},"gpu_busy_ms_per_present":5.994,"worker_busy_pct":{"queue worker 0x0":3.094},"top_phases_ms_per_frame":{"Graphics.Draw":9.564,"Graphics.Draw.draw_and_resource_release":8.314,"Vulkan.DrawFromRecipe":8.032,"Graphics.DrawWithRecipe":8.004,"Graphics.DrawWithRecipe.draw_and_resource_release":7.988,"Recorder.Submit":4.267,"Driver.Packet":3.665,"Driver.Packet.draw":2.896},"trace_dropped":false,"trace":"aps5-trace-976583da31c3-9616.json.gz"}Slowest frames (largest slices inside each, inclusive)
- present 266: 134.2 ms at 485 ms: Driver.WorkerWait (queue worker 0x0) 129.8, Driver.WorkerWait.idle_and_completion_poll (queue worker 0x0) 129.7, Graphics.Draw (draw committer) 10.9, Graphics.Draw.draw_and_resource_release (draw committer) 9.5
- present 287: 129.7 ms at 2998 ms: Driver.WorkerWait (queue worker 0x0) 125.3, Driver.WorkerWait.idle_and_completion_poll (queue worker 0x0) 125.2, Graphics.Draw (draw committer) 10.8, Graphics.Draw.draw_and_resource_release (draw committer) 9.5
- present 279: 129.1 ms at 2033 ms: Driver.WorkerWait (queue worker 0x0) 124.9, Driver.WorkerWait.idle_and_completion_poll (queue worker 0x0) 124.8, Vulkan.DrawFromRecipe (draw committer) 9.7, Graphics.DrawWithRecipe (draw committer) 9.7
- present 296: 127.4 ms at 4075 ms: Driver.WorkerWait (queue worker 0x0) 123.1, Driver.WorkerWait.idle_and_completion_poll (queue worker 0x0) 123.0, Graphics.Draw (draw committer) 9.7, Graphics.Draw.draw_and_resource_release (draw committer) 8.5
- present 285: 127.3 ms at 2751 ms: Driver.WorkerWait (queue worker 0x0) 122.9, Driver.WorkerWait.idle_and_completion_poll (queue worker 0x0) 122.7, Graphics.Draw (draw committer) 10.0, Vulkan.DrawFromRecipe (draw committer) 8.4
Threads (ms per frame)
| thread | busy | wait | untraced | in slices < 20 us | largest |
|---|---|---|---|---|---|
| title | 1.4 (1 %) | 0.0 (0 %) | 119.2 | 0.1 | Recorder.Sync 1.4 |
| queue worker 0x0 | 3.0 (2 %) | 116.4 (97 %) | 1.2 | 4.1 | Driver.Packet 3.0, Driver.EndSubmission 0.0 |
| draw committer | 22.0 (18 %) | 0.1 (0 %) | 98.4 | 0.1 | Graphics.Draw 9.6, Vulkan.DrawFromRecipe 8.0 |
| presenter | 0.9 (1 %) | 0.5 (0 %) | 119.1 | 0.0 | VideoOut.Flip 1.4, Driver.Present 0.0 |
| gpu | 1.6 (1 %) | 0.0 (0 %) | 118.9 | 0.0 | batch 1.6 |
Largest slices (ms per frame, inclusive, all threads): Driver.WorkerWait 116.4, Driver.WorkerWait.idle_and_completion_poll 116.3, Graphics.Draw 9.6, Graphics.Draw.draw_and_resource_release 8.3, Vulkan.DrawFromRecipe 8.0
Longest waits
- Driver.WorkerWait (queue worker 0x0) 6.0 ms at 6226 ms, present 313
- Driver.WorkerWait (queue worker 0x0) 5.3 ms at 2120 ms, present 279
- Driver.WorkerWait (queue worker 0x0) 5.0 ms at 6059 ms, present 312
- Driver.WorkerWait (queue worker 0x0) 4.9 ms at 92 ms, present 262
- Driver.WorkerWait (queue worker 0x0) 4.9 ms at 5496 ms, present 307
Largest GPU batches (GPU ranges inside, and the CPU slices that recorded each, inclusive)
- batch 3645: 2.1 ms at 1561 ms, present 275: GPU no ranges; recorded by Vulkan.DrawFromRecipe (draw committer) 0.2, Graphics.DrawWithRecipe (draw committer) 0.2, Graphics.DrawWithRecipe.draw_and_resource_release (draw committer) 0.2, Recorder.Submit (draw committer) 0.1
- batch 3055: 2.1 ms at 345 ms, present 264: GPU no ranges; recorded by Vulkan.DrawFromRecipe (draw committer) 0.5, Graphics.DrawWithRecipe (draw committer) 0.5, Graphics.DrawWithRecipe.draw_and_resource_release (draw committer) 0.5, Recorder.Submit (draw committer) 0.1
- batch 2996: 2.1 ms at 227 ms, present 263: GPU no ranges; recorded by Vulkan.DrawFromRecipe (draw committer) 0.3, Graphics.DrawWithRecipe (draw committer) 0.3, Graphics.DrawWithRecipe.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.1
- batch 3104: 2.1 ms at 440 ms, present 265: GPU no ranges; recorded by Vulkan.DrawFromRecipe (draw committer) 0.2, Graphics.DrawWithRecipe (draw committer) 0.2, Graphics.DrawWithRecipe.draw_and_resource_release (draw committer) 0.2, Recorder.Submit (draw committer) 0.1
- batch 3704: 2.1 ms at 1674 ms, present 276: GPU no ranges; recorded by Vulkan.DrawFromRecipe (draw committer) 0.3, Graphics.DrawWithRecipe (draw committer) 0.3, Graphics.DrawWithRecipe.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.1
AI-assisted: yes (Claude Code)
|
Related: #8802 fixes failure-memo lifetime in Your repeated-address deferral addresses a different case, but the nearby map-import code overlaps. #8802 does not depend on the deferral; I can rebase it and adapt its replacement-owner regression to first-use import if #8622 lands first. Please let me know your preferred order. |
A guest that keeps remapping the same buffer paid a whole-range host import at every map and its retirement at every unmap. SuperTuxKart maps and unmaps one 2 MiB direct-memory buffer about 48 times a frame; the first GPU use imports only the window it reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8cd77b2 to
bf66eec
Compare
|
@JJenkx #8802 landed first, so I rebased this onto it (bf66eec) and adapted its replacement-owner regression to the first-use import, as you suggested:
Tested on a Radeon 860M, Windows 11 26300, WinLibs GCC 15.2.0, Release, with Edit: an earlier version of this comment said |
|
AMD/Linux data point on a second title, measured next to #7465 (which defers small imports by size). Setup
On
This PR helps here, and the result looks consistent with what it targets: a range mapped again at the same address and size. The ~2,600 remaining refusals suggest some of this title's ranges come back at a different size, which a size gate like #7465's also covers. This is one machine and one scene. AI-assisted: yes (Claude Code); results above were run on this machine. |
|
Protocol note on my measurement above (comment 6328229023): it does not meet the performance-report protocol's "do not redirect the log" rule. The game ran under AI-assisted: yes (Claude Code) |
|
Lodoss rerun under the performance-report protocol. It replaces my earlier Lodoss comment above, whose game output was captured to files (see my protocol note). The direction is the same. Setup
The PR runs (56.3–56.4 FPS) are above both AI-assisted: yes (Claude Code); results above were run on this machine. |
|
Checked the diff, |
…status and reason strings Only the PR's own commit f916937 (Ocsp.cpp, its test and debt bullet); the upstream merges the PR branch carries (boykopovar#9643, boykopovar#9642, boykopovar#8622, boykopovar#9992, boykopovar#10059) are left out. Ocsp.cpp joins our multi-file source list.
What
ImportMappedRanges(#1961) imports a GPU-mapped range whole when it is mapped. This is right for a large pool mapped once. For a buffer the guest maps and unmaps over and over at the same address, each map pays a whole-range import on the mapping thread and each unmap retires it.SuperTuxKart (PPSA69421) maps and unmaps one 2 MiB direct-memory buffer,
0x255200000, about 48 times a frame (APS5_TRACE_MEMORY). Each time it ismap direct 0x255200000+0x200000 phys=0x54e00000 prot=0x33. In a 75 s menu run,APS5_TRACE_HOST_IMPORTlogged 21,697 imports by map (19,980 of them of that buffer). On Windows, a direct mapping with a single view is committed private memory, and its bytes are saved at unmap and copied back at map. The pages differ at every map, so the import cannot be kept across the unmap.The table now remembers the ranges (address and size) it imported at map. A range mapped again with the same address and size, and no import left over it, is no longer imported at map; its first GPU use imports it, as before #1961. The first mapping of a range is still imported at map, so the PPSA36082 case #1961 describes (pools mapped once while loading) is unchanged. A range whose import still exists is still checked at map, so the stale-probe repair keeps validating it there. The set is cleared when the table moves to another device and by
ClearHostImports.agc_driver_host_import_at_mapexpected a range mapped again to be imported at map. It now expects that range not to be imported at map, and expects its first GPU use (a fill) to import it. #8802's replacement-owner regression now expects the replacement to retry its predecessor's failed import on first use rather than at map.importAtMapOverBudgetTestsandimportRequesterTestsregister fresh ranges at heap addresses earlier fixtures used, so they start fromClearHostImports.Tested
Windows 11 26300, AMD Ryzen AI 7 350 / Radeon 860M (driver 32.0.13058.8001), WinLibs GCC 15.2.0, Release.
agc_driver_host_import_at_mappasses; withGuestBufferMemory.cppfrommainit fails with "a range mapped again was imported at map instead of on first use".agc_driver_graphicspasses. Onmain'sGuestBufferMemory.cppthe adapted fix(agc): retain map import failures across unrelated mappings #8802 check fails with "a replacement owner was imported again at map instead of on first use".agc_driver_graphics, the host-import, import-settle, sparse-run and BDA tests andagc_buffer_poolpass withANYPS5_REQUIRE_VULKAN=1andANYPS5_NO_SHADER_CACHE=1(25 of 25,agc_host_import_sparseskips). The Khronos validation layer is not installed on this machine.mainatec7eacc62and this PR rebased onto it, each a clean build of its commit.APS5_TRACE_SECONDS=40:8mainec7eacc62d58bf66eeccfdc9APS5_TRACE_SECONDS=95:20mainec7eacc62d58bf66eeccfdc9The menu gains 14 %. The race on
mainis bound by texture copies (about 400 ms a frame), and the change is within run-to-run noise there. Onmain+ #8538 + #6718, earlier and with window-title FPS, the race went from 7.55 to 7.8, one run each.Summary lines (menu)
{"commit":"ec7eacc62d58","dirty":false,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"40:8"},"gpu":"AMD Radeon(TM) 860M Graphics","driver":"AMD proprietary driver 24.30.58.08 (LLPC)","os":"Windows 10.0.26300","cpu":"AMD Ryzen AI 7 350 w/ Radeon 860M","cpu_threads":16,"memory_mib":31866,"title_id":"PPSA69421","title":"SuperTuxKart","content_version":"00.001.000","resolution":"1920x1080","window":{"spec":"seconds 40:8","first_present":328,"ms":8093.236},"presents":83,"frame_ms":{"p50":96.570,"p90":102.851,"p99":110.242,"max":110.242},"gpu_busy_ms_per_present":5.585,"worker_busy_pct":{"queue worker 0x0":3.268},"top_phases_ms_per_frame":{"Graphics.Draw":5.732,"Graphics.Draw.draw_and_resource_release":4.813,"Vulkan.DrawFromRecipe":4.478,"Graphics.DrawWithRecipe":4.460,"Graphics.DrawWithRecipe.draw_and_resource_release":4.451,"Recorder.Submit":3.309,"Driver.Packet":3.136,"Driver.Packet.draw":2.479},"trace_dropped":false,"trace":"aps5-trace-ec7eacc62d58-14020.json.gz"} {"commit":"bf66eeccfdc9","dirty":false,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"40:8"},"gpu":"AMD Radeon(TM) 860M Graphics","driver":"AMD proprietary driver 24.30.58.08 (LLPC)","os":"Windows 10.0.26300","cpu":"AMD Ryzen AI 7 350 w/ Radeon 860M","cpu_threads":16,"memory_mib":31866,"title_id":"PPSA69421","title":"SuperTuxKart","content_version":"00.001.000","resolution":"1920x1080","window":{"spec":"seconds 40:8","first_present":363,"ms":8018.855},"presents":94,"frame_ms":{"p50":85.128,"p90":90.045,"p99":100.765,"max":100.765},"gpu_busy_ms_per_present":5.846,"worker_busy_pct":{"queue worker 0x0":3.576},"top_phases_ms_per_frame":{"Graphics.Draw":6.121,"Graphics.Draw.draw_and_resource_release":5.155,"Vulkan.DrawFromRecipe":5.054,"Graphics.DrawWithRecipe":5.029,"Graphics.DrawWithRecipe.draw_and_resource_release":5.018,"Recorder.Submit":3.297,"Driver.Packet":2.998,"Driver.Packet.draw":2.338},"trace_dropped":false,"trace":"aps5-trace-bf66eeccfdc9-34928.json.gz"}Traces:
mainmenu, this PR menu,mainrace, this PR racetools/trace_digest.pyonmain(menu)seconds 40:8 from present 328: 83 presents, frame p50 96.6 / p90 102.9 / p99 110.2 / max 110.2 ms, GPU busy 5.6 ms per present
AMD Radeon(TM) 860M Graphics, AMD proprietary driver 24.30.58.08 (LLPC), Windows 10.0.26300, 1920x1080, commit ec7eacc, dropped: no
{"commit":"ec7eacc62d58","dirty":false,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"40:8"},"gpu":"AMD Radeon(TM) 860M Graphics","driver":"AMD proprietary driver 24.30.58.08 (LLPC)","os":"Windows 10.0.26300","cpu":"AMD Ryzen AI 7 350 w/ Radeon 860M","cpu_threads":16,"memory_mib":31866,"title_id":"PPSA69421","title":"SuperTuxKart","content_version":"00.001.000","resolution":"1920x1080","window":{"spec":"seconds 40:8","first_present":328,"ms":8093.236},"presents":83,"frame_ms":{"p50":96.57,"p90":102.851,"p99":110.242,"max":110.242},"gpu_busy_ms_per_present":5.585,"worker_busy_pct":{"queue worker 0x0":3.268},"top_phases_ms_per_frame":{"Graphics.Draw":5.732,"Graphics.Draw.draw_and_resource_release":4.813,"Vulkan.DrawFromRecipe":4.478,"Graphics.DrawWithRecipe":4.46,"Graphics.DrawWithRecipe.draw_and_resource_release":4.451,"Recorder.Submit":3.309,"Driver.Packet":3.136,"Driver.Packet.draw":2.479},"trace_dropped":false,"trace":"aps5-trace-ec7eacc62d58-14020.json.gz"}Slowest frames (largest slices inside each, inclusive)
Threads (ms per frame)
Largest slices (ms per frame, inclusive, all threads): Driver.WorkerWait 93.9, Driver.WorkerWait.idle_and_completion_poll 93.8, Graphics.Draw 5.7, Graphics.Draw.draw_and_resource_release 4.8, Vulkan.DrawFromRecipe 4.5, Graphics.DrawWithRecipe 4.5, Graphics.DrawWithRecipe.draw_and_resource_release 4.5, Recorder.Submit 3.3, Driver.Packet 2.5, Driver.Packet.draw 2.4
Longest waits
Largest GPU batches (GPU ranges inside, and the CPU slices that recorded each, inclusive)
tools/trace_digest.pywith this PR (menu)seconds 40:8 from present 363: 94 presents, frame p50 85.1 / p90 90.0 / p99 100.8 / max 100.8 ms, GPU busy 5.8 ms per present
AMD Radeon(TM) 860M Graphics, AMD proprietary driver 24.30.58.08 (LLPC), Windows 10.0.26300, 1920x1080, commit bf66eec, dropped: no
{"commit":"bf66eeccfdc9","dirty":false,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"40:8"},"gpu":"AMD Radeon(TM) 860M Graphics","driver":"AMD proprietary driver 24.30.58.08 (LLPC)","os":"Windows 10.0.26300","cpu":"AMD Ryzen AI 7 350 w/ Radeon 860M","cpu_threads":16,"memory_mib":31866,"title_id":"PPSA69421","title":"SuperTuxKart","content_version":"00.001.000","resolution":"1920x1080","window":{"spec":"seconds 40:8","first_present":363,"ms":8018.855},"presents":94,"frame_ms":{"p50":85.128,"p90":90.045,"p99":100.765,"max":100.765},"gpu_busy_ms_per_present":5.846,"worker_busy_pct":{"queue worker 0x0":3.576},"top_phases_ms_per_frame":{"Graphics.Draw":6.121,"Graphics.Draw.draw_and_resource_release":5.155,"Vulkan.DrawFromRecipe":5.054,"Graphics.DrawWithRecipe":5.029,"Graphics.DrawWithRecipe.draw_and_resource_release":5.018,"Recorder.Submit":3.297,"Driver.Packet":2.998,"Driver.Packet.draw":2.338},"trace_dropped":false,"trace":"aps5-trace-bf66eeccfdc9-34928.json.gz"}Slowest frames (largest slices inside each, inclusive)
Threads (ms per frame)
Largest slices (ms per frame, inclusive, all threads): Driver.WorkerWait 81.9, Driver.WorkerWait.idle_and_completion_poll 81.8, Graphics.Draw 6.1, Graphics.Draw.draw_and_resource_release 5.2, Vulkan.DrawFromRecipe 5.1, Graphics.DrawWithRecipe 5.0, Graphics.DrawWithRecipe.draw_and_resource_release 5.0, Recorder.Submit 3.3, Driver.Packet 2.3, Driver.Packet.draw 2.2
Longest waits
Largest GPU batches (GPU ranges inside, and the CPU slices that recorded each, inclusive)
Skipping every map-time import gave 8.7 FPS in the same menu. Most of the remaining gap is the ranges imported at their first map that the GPU never reads: 322 imports, 961 MiB live, against 3 imports, 130 MiB. That is the trade #1961 describes, and this PR leaves it alone.
#7465 changes the same lines: it defers map imports of ranges up to 64 KiB. The 2 MiB buffer here is not covered by it.
tools/pr_overlap.pyfound no other overlap among the PRs it could compare.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)