wip(assembler): round S8 -- region rebuilds no longer stall admission; result backlog capped
voxel.CoreRegionConcurrentAdmission (default on): tiles independent of the entering region keep submitting while a region page compiles; pages are immutable shared_ptr owners so running readers survive eviction. 6 m/s: 11 whole-pass skips -> 0, walkable ring ready at every centre change. voxel.StreamingResultBacklogCap=256 bounds finished results (slow-apply worst case 125 -> 76 MB). Spawn unchanged at ~7.7 s: LOD8 is 46% of worker time. At 60 m/s + teleport the collision ring is outrun (102/113 centres). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
1 parent
5eb9ee76ff
commit
8440adc742
10 files changed
+1011
-78
No files matched your search
@@ -584,6 +584,13 @@ driven by `EditorBrush*` props.
|
||||
admission count. `voxel.StreamingDynamicNearReserve=1` holds the authored near reserve while moving
|
||||
or before the walkable gate, then releases it to coarse work after the stationary ring is ready.
|
||||
Stationary player ≈ free. (Old per-frame O(loaded×desired) scan = 22ms.)
|
||||
Core region compilation is a separate resource gate. With the default
|
||||
`voxel.CoreRegionConcurrentAdmission=1`, tile keys that need the pending region are withheld, while
|
||||
independent keys may use remaining worker slots. `0` restores the all-admission wait. Region pages
|
||||
are built off the lookup map, published as immutable shared pages, and reclaimed when the final
|
||||
reader releases its shared owner. `voxel.StreamingResultBacklogCap=256` independently bounds queued
|
||||
result payloads plus active tile tasks and held prequeue results; `0` disables this memory backstop.
|
||||
Result count is not used as a worker-slot count.
|
||||
- **LOD** changes HOT-SWAP (`LoadTile` only, never unload-first) → no holes. LOD
|
||||
reconciliation lives in the PERSISTENT per-frame submit loop (same loop as new-chunk loads),
|
||||
NOT as a one-shot on the boundary-cross frame — a one-shot drops every chunk past the task
|
||||
@@ -1565,6 +1572,43 @@ the recipe version remains unchanged. Null-RHI runs do not prove player-visible
|
||||
[`Standalone/Research/WorldAssemblerM3/Round11/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round11/REPORT.md)
|
||||
for the audit counts, RMC review, quality matrix, commands and binary hashes.
|
||||
|
||||
### 8.29 Concurrent region admission and bounded result backlog — World Assembler S8 / M3 Round 12
|
||||
|
||||
The S7 moving trace found `bCoreRegionCompilePending` returning before all tile submissions. Each
|
||||
such update could leave most slots unused while a new player center requested a region page. The
|
||||
default `voxel.CoreRegionConcurrentAdmission=1` lets `LoadCoreTile` continue for keys outside the
|
||||
pending and in-flight region sets. Keys that need those sets wait for publication; setting the CVar
|
||||
to `0` restores the old all-admission gate for an A/B control. This changes scheduling only.
|
||||
|
||||
`World::compileTileRegion` builds region pages without mutating pages already in use, then publishes
|
||||
them under the region-map lock. `generateTile` copies a `shared_ptr` while holding the map's shared
|
||||
lock and keeps it for the whole mesh read. Evicting or replacing a map entry therefore cannot free a
|
||||
page under an existing worker. The actor's shared `WorldLock` prevents a world edit/reset while a
|
||||
tile reader or region compiler is active; `EndPlay` waits for the shared active-task count before
|
||||
destroying the actor's UObject state.
|
||||
|
||||
The result backlog has its own backpressure control. `voxel.StreamingResultBacklogCap=256` counts
|
||||
queued MPSC results, active tile-generation tasks and held visible-LOD0 prequeue results. Reaching
|
||||
the cap stops new tile admissions until apply drains results or active tasks retire. It does not make
|
||||
finished results consume worker slots in the normal admission count. `0` is the uncapped negative
|
||||
control; the Core-off legacy test also exercises the default cap.
|
||||
|
||||
On the 25 cm owner SurfaceWorld plan, the matched 6 m/s CVar-off/on runs both completed 11 region
|
||||
requests (one initial desired set plus ten center moves). The old gate recorded 11 global scheduler
|
||||
skips; concurrent admission recorded none and submitted 110 unrelated tiles with no dependent-key
|
||||
declines. All eleven changing support centers had the nine-tile walkable ring ready immediately.
|
||||
Accumulated pending windows were about 0.43 s, but measured compiler wall time totaled about 11 ms.
|
||||
At 60 m/s with a 400 m teleport, the trace recorded 113 region requests, 782 independent submissions
|
||||
and 983 dependent-key declines. Most support centers advanced before their nine-tile ring could
|
||||
become ready, so the high-speed gate still fails its travel-time target.
|
||||
|
||||
The shared result trace now records `queued_peak`, peak payload bytes, the configurable cap, and cap
|
||||
stops. A slow-apply teleport stress run peaked at 256 results / 76.2 MB with the default cap; the
|
||||
uncapped control reached 1,577 / 125.1 MB. Payload bytes exclude queue-node and allocator overhead.
|
||||
The cap kept the observed backlog finite without reinstating the S6/S7 finished-result worker-slot
|
||||
decline. Full timings, per-center records, quality checks and hashes are in
|
||||
[`Standalone/Research/WorldAssemblerM3/Round12/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round12/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
|
||||
|
||||
Reference in new issue
Block a user