WorldAssemblySurfaceProfileV1 on the native SurfaceWorld recipe and plan; version 0 'natural' is omitted from serialized identity, so the owner world is unchanged. periodicHills (seeded cosine hills, plan-time grade <= 15 deg), mirroredRelief (cap mirrors the floor by lambda, clearance checked) and flatField share one profile function for points, lattice classification and exact cosine-extrema intervals (0 interval misses in brute-force audits). Style-override fixtures with planned passages. Cold whole view about 1.33 s for each profile vs 1.74 s natural SW (Clang). Owner hashes identical to L52; fast/medium/full PASS. Research R22: SurfaceWorld critical path to about 1 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
9.0 KiB
R22 — What stands between SurfaceWorld and ~1 s?
Metric: This report treats the target as all-view CPU tile completion. In the profiled SW run, the near ring is CPU-ready at 0.524 s and the whole view at 1.572 s. Neither timestamp means the tiles are uploaded, resident, or presented; those need a separate viewer measure.
Critical path
World::compile builds the shape world before tile generation (World::compile, FStandaloneShapeWorld::Build). In the headless pipeline, the pool starts with shape-free tiles, then waits for the shape-build future before queueing the full desired set. L52 had 0 of 2,370 shape-free tiles, so no tile work overlapped shape setup (pipeline barrier).
Shape construction is partly parallel: interval, candidate-band, and detail row scans use the host scheduler, which caps helper threads at eight even when the request specifies twelve (scheduler). Sign-edge completion and far-parent/bin construction are serial portions.
After shape publication, twelve persistent tile workers pull jobs dynamically from a shared priority heap (worker loop). The queue prioritizes the central 27 LOD0 tiles, then coarser LODs from 8 down to 2, then distant LOD0/1 detail (priority assignment). That is a dispatch preference, not an LOD completion barrier. Each worker generates one tile at a time through World::generateTile.
For SW, the profiled worker sum is 12.745 worker-seconds: a 1.062 s ideal drain on twelve workers, against about 1.065 s from shape completion to the last tile. That indicates an aggregate work-saturated tail; the data leaves little room for scheduling or idle-time gains. The last ready group is LOD0/1 detail: full_detail_ready and whole_view_ready coincide. Queue order can contribute to when those tiles run, but the current trace cannot quantify queue delay or identify a slow final tile. Per-LOD averages do not rule out an outlier. WholeViewReady is the maximum CPU Tile.CompletedAt, not GPU residency or presentation (readiness calculation).
Shape setup
SW’s 0.437 s setup breaks down to about 36 ms local shapes, 78 ms intervals and signs, 259 ms surface band, and 54 ms far parents. The surface band includes about 241 ms of parallel detail application and 18 ms of serial sign-edge completion. FI’s 0.887 s setup has a similar interval stage, but its 707 ms surface band includes about 479 ms of serial sign-edge repair and 227 ms of detail application. These splits are in the SW profile and FI profile.
The interval stage packs rock runs and passage void crossings into candidate bands; the surface-band stage applies detail and repairs sign-edge distances; far-parent construction builds coarse geometry and spatial bins (shape stages). Raising the helper cap from eight to twelve has an ideal ceiling near 0.10 s for SW and 0.09 s for FI. FI’s sign-edge pass has a larger theoretical opportunity, up to about 0.44 s, but needs deterministic parallel handling of shared packed-grid words.
Regional compilation could help near-ring latency, but compileTileRegion requires an already compiled base world (region API). The viewer has a neighborhood-first/background-full-build scaffold, but current call sites select full-build mode (viewer build path). Deferring far parents can move roughly 54 ms for SW or 50 ms for FI off the near-ring path, but does not eliminate work needed for far tiles.
A warm shape cache could save at most the build time before load/decode cost. planHash alone is not a safe key: the two L52 logs share a plan hash but differ in resolved-layout identity. The key must include resolved layout, bounds, build switches, and version. The current shape arrays exceed 337 MiB, and a cache cannot help a cold run.
Far LODs and safe skips
SW LOD6 connector repair costs 1.335 worker-seconds and adds 5,070 triangles; LOD8 costs 2.884 worker-seconds, including 1.348 seconds for its marching-cubes grid. Together LOD6–8 account for about 0.49 s of ideal twelve-worker drain. That is a ceiling for removing all their work, not a safe forecast: connector walls close gaps, and LOD8 contributes to the horizon. The existing screen-space gate checks only the closest native-heightfield tile at each LOD, not every far tile or connector (gate).
Earlier gates found that doubling connector station spacing introduced holes, while doubling refinement spacing failed image and topology checks (Linux15 quality gate). LOD8 interior sampling was already reduced to marching-cubes spacing (Round14 change). Prefer exact kernel improvements or later dispatch until current-source quality gates prove a coarser setting safe.
SW’s block proof found 960 unknown boxes and no whole-tile skips; FI’s proof found 216 whole-tile skips, but classification itself cost 22.5 worker-seconds. Also distinguish proof skips from the mesher’s existing Z-band early return, which can yield an empty mesh before density sampling (Z-band return). L52 does not count those returns per tile.
Ranked plan
-
Instrument the tile drain first. This has no direct speed gain, but is required to choose the right optimization. Keep the unprofiled paired medians as the performance score. SW’s median was 1.718 s, so reaching 1 s requires about 0.72 s off; in the profiled decomposition, tile drain would need to fall from about 1.065 s to 0.493 s. Even after the ideal shape scheduler gain, about 5.63 worker-seconds of tile work still need to go.
-
Target measured tile kernels. This is the main path to the SW target. One exact-output candidate is skipping skirt faces that the viewer masks as hidden; the absolute ceiling is about 0.15 s at twelve-way ideal drain, and the real saving will be smaller. FI needs a much larger reduction: roughly 32–38 worker-seconds of its 48.3 worker-seconds, depending on shape improvements. LOD0 alone costs 28.6 worker-seconds, so far-tier work cannot get FI near 2 s.
-
Reduce serial shape cost where measured. Test the helper cap increase and, for FI, a deterministic parallel sign-edge repair. The ceilings are about 0.10 s for SW and about 0.53 s for FI combined. These are useful gains, but insufficient alone.
-
Optimize first playable content separately. Neighborhood-first shape setup and deferred far parents may improve the near ring or first presentation, not all-view completion. Measure CPU ring-ready, upload/resident, and first-presented times separately.
-
Consider a warm shape cache only for repeated runs. It can save up to 0.44 s SW or 0.89 s FI before cache I/O, but provides no cold-run gain.
Instrumentation spec
CpuTileTimeline already supports queued, started, and finished events, but L52’s headless logs do not include them (timeline hooks). Enable it in the headless path and add, per event, one monotonic timestamp, tile key and LOD, enqueue rank/tier, worker ID, queue depth, and active-worker count. Derive queue wait (dispatch − enqueue) and service time (finish − dispatch), then report p50/p95/max by LOD and priority tier, plus the last 20 completions and worker idle intervals while the queue is nonempty.
Add per-tile stage spans for classification, field/column sampling, marching-cubes work, connector repair, ground/cap, skirts, and mesh assembly; count Z-band rejects separately from proof skips. Buffer events per worker and dump after the run so logging does not sit inside the queue lock. In the viewer, pair the CPU trace with upload, residency, and first-useful-present events; those are separate from CPU whole-view readiness.