wip(assembler): round S12 -- short ready queue keeps workers fed between ticks: full set 6.0 s -> 4.9 s

voxel.StreamingReadyQueueDepth=8 admits one extra worker-set of prioritized
tasks; voxel.StreamingBackgroundWorkerCap=1 sizes slots to the 8 TaskGraph
background workers actually running tile tasks. Full set 5.96 -> 4.91 s,
LOD0 1.40 -> 1.09 s, ring 0.49 -> 0.51 s, 40 m/s ring 75/75. Tick p95
+0.6 ms spawn / +0.26 ms walk, max flat. No geometry change.
Report: Standalone/Research/WorldAssemblerM3/Round16.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-19 14:29:38 +02:00
1 parent dd9bfd3217
commit 212814a75c
8 files changed
+554 -36

No files matched your search

+49
View File
@@ -1707,6 +1707,55 @@ ready well before that far-LOD tail. Geometry and collision arithmetic do not ch
versions stay unchanged.
See [`Standalone/Research/WorldAssemblerM3/Round15/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round15/REPORT.md).
### 8.33 Streaming worker supply and tick-independent task pickup — World Assembler S12 / M3 Round 16
The S11 trace showed that admission was paced by the actor tick: typical tiles finished within one
18 ms frame, while the eight TaskGraph background workers waited for the next scheduler pass to
receive another task. The host exposed ten TaskGraph workers (two foreground, eight background),
and the tile tasks ran only on the eight background workers. The shared scheduler now admits up to
one additional worker-set of prioritized tile tasks (`voxel.StreamingReadyQueueDepth`, default 8,
clamped to the effective worker count). These tasks are still selected and submitted on the game
thread through the existing desired-tile ordering; UE's background executor dispatches queued work
as each worker becomes free. There is no worker-owned continuation list, and no UObject, RMC, or
desired-set mutation moves off the game thread.
`voxel.StreamingBackgroundWorkerCap=1` sizes the streaming admission slots to
`FTaskGraphInterface::GetNumBackgroundThreads()`. It does not lower `GetMaxConcurrentTasks()` or the
worker limit used inside Core's parallel generation. `0` restores the old logical-core-derived
streaming cap. The `worker_backend_config` and `streaming_worker_cap_readback` trace events record
the CVar readback, logical core count, TaskGraph and global queued-pool sizes, task API, and effective
slot count. Each tile row records its submission, worker start/end, and OS thread ID. The external
BuildHost sample also records process thread count and working set; its eight tile IDs match the
TaskGraph background pool. RMC's inspected async collision path queues through `GThreadPool`, which
is a separate 10-thread pool; it does not occupy those eight TaskGraph worker IDs. Arbitrary UE
background tasks can share TaskGraph background workers, so the pool count alone does not imply
those workers are idle outside the measured tile task intervals.
Admission remains shared by `LoadTile` and `LoadCoreTile`. The queue-aware dynamic near reserve is
at least the ready-queue depth while moving or before the stationary walkable gate is ready, capped
at one less than the worker slots. Horizon work uses a separate coarse cap; while moving, ordinary
LOD0 admission stops at the actual worker-slot count and critical collision/edit work retains its
existing higher admission cap. Thus queued far work cannot consume the reserved near capacity.
`bStreamingPlayerMoving` is captured on the game thread for both admission paths. Existing
`GenerationEpoch` / `DesiredEpoch` and per-request cancellation checks still reject stale tasks and
results; no preprepared desired list survives a set change.
On the matched 25 cm SurfaceWorld startup trace, queue depth 8 plus the 8-worker slot cap brought the
2,578-tile ready time to 4.911 s (the matched queue-depth-zero control took 7.024 s). The LOD0
worker tail ended at trace time 1.167 s; its last apply was at 1.087 s on the actor startup clock,
against S11's 1.403 s. The stationary 3×3 collision-ready ring was ready at 0.509 s, close to the S11
0.488 s measurement. The per-tile trace contains all 2,578 initial requests and shows eight active
workers at peak, 29.432 worker-seconds, and 6.573 seconds of inter-task idle time summed across the
eight slots. 500 ms busy-worker equivalents, per-LOD completion and each slot's inter-task gap are
saved under `Saved/BuildHost/Round16/`. The full table and matched controls are in the Round 16
report.
Foreground task priorities were tested and rejected: they increased spawn/walk `UWorld::Tick`
tails despite occupying more TaskGraph workers. The shipped priorities stay `BackgroundHigh` for
near and `BackgroundNormal` for horizon tasks. The task-pickup changes do not alter density,
triangulation, collision, or Core output, so no recipe version changes.
See [`Standalone/Research/WorldAssemblerM3/Round16/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round16/REPORT.md).
## 9. Multiplayer model (listen-server first, dedicated-friendly)
> **Status: transport is DESIGN ONLY — nothing is networked in-tree yet** (no `Replicated`/`HasAuthority`/RPCs; a