perf(generation): field-exact LOD0 overhead removal; the unknown bucket is Core.dll
Field-preserving floor round (Codex; reviewed by me against the code):
- exact per-(sample, passage) caching of native/generic floor projections and walkable-air
checks, behind voxel.FloorRound1PassageProjectionCache
- a zero-work disabled path for VoxelDensityProfile::FScopedTimer, unchanged when enabled
- pointer / range-for iteration in the proven-hot tunnel, passage, spatial and candidate loops
(TArray RangeCheck was ~6.5% of LOD0 samples on the Development binaries the owner plays on)
- FVector2D temporaries replaced with scalar doubles, same operations in the same order
- FSurfaceColumn made trivial, so thread-local construction does no work. Verified safe:
ComputeSurfaceColumn writes all five outputs unconditionally before any branch, and every read
of Box.Cols is gated by Box.Computed
Verified: export OBJ byte-identical (b3e5f4c3..9b377); capability 20,830 / 10,909; all 8
interleaved game runs gave identical totals (841 tiles / 669,834 triangles static, 2,348 /
1,985,216 moving, the same as previous rounds). Per-tile identity for the always-on changes still
needs a check against a stored trace; that is queued first in the next round.
Game path (sampler off, two interleaved runs each):
projection-cache switch alone: neutral (static worker +0.41%, moving -0.05%)
vs the previous round (cfad3d1, same harness; cross-round numbers reproduced within ~1% here):
LOD0 generation p50 static 76.6 -> 65.8 ms (-14%), moving 72.4 -> 59.5 ms (-18%)
LOD0 request p50/p95 moving 79.4/158.5 -> 67.6/137.6 ms
worker seconds static 39.2 -> 33.4, moving 113.7 -> 97.9
The always-on changes carry the gain; they have no switch, so this is a cross-round comparison.
The sampler's ~12.9% "unknown" LOD0 leaf is engine code: UnrealEditor-Core.dll + RVA 0xC080,
without a Core PDB. The old FSurfaceColumn label is gone. Next round names it by its callers.
PERF-SAMPLED.md: corrected a sentence that repeated my false "daytime use" explanation.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TaFdXhTdYMkW1xrV6ApT6Y
This commit is contained in:
1 parent
b839edd3a3
commit
ab4bbe3680
9 files changed
+629
-170
No files matched your search
@@ -492,6 +492,13 @@ shape draws for inter-strate passages are keyed by `(seed, upper-strate index, c
|
||||
per-value salt)` through `VoxelHash`, so one passage's connection count cannot shift any later
|
||||
passage. Global passage settings were removed from `VoxelSettings`.
|
||||
|
||||
The repeated floor queries use the same `thread_local` passage state: `FPassageEvaluationCache` owns
|
||||
one indexed `FloorProjections` entry per passage, keyed by exact double `(X,Y,Z)` equality for the
|
||||
current sample. Native projection, generic fallback projection, and walkable-air classification
|
||||
reuse the cached float outputs and validity bits; manager lifetime, layout version, and chunk changes
|
||||
invalidate the cache. `voxel.FloorRound1PassageProjectionCache` is an A/B switch only. It changes no
|
||||
projection arithmetic and no density value; a cache hit is an exact reuse of the first result.
|
||||
|
||||
After each passage's XY is selected, `GeneratePassages` asks **both** participating strates for a
|
||||
player-fit source point through the pure free function `VF_SuggestLandingPoint`
|
||||
(`VoxelCaveMorphology`).
|
||||
@@ -674,6 +681,17 @@ driven by `EditorBrush*` props.
|
||||
**Used ONLY for integer-XY queries**; fractional queries compute directly → bit-identical. Don't
|
||||
re-introduce a ChunkZ key, don't feed it fractional coords. (`GetSurfaceHeightAt`'s own `OC_*` oracle
|
||||
cache is separate and still per-chunk — lower volume, not worth the LRU.)
|
||||
- **Surface-column construction (field-preserving follow-up)**: `FSurfaceColumn` is intentionally a
|
||||
trivial payload. `ComputeSurfaceColumn` writes all five outputs before publishing `Computed`, so
|
||||
its default member initialization was never observable; removing that generated TLS leaf avoids
|
||||
constructor work without changing a height or density. Integer queries still read the cached
|
||||
payload, and fractional queries still use the same direct locals.
|
||||
- **Sampler unknown-source audit**: the earlier plugin-side `FSurfaceColumn` constructor PCs no longer
|
||||
occur after the trivial-payload change. The largest remaining LOD0 unknown cluster in the final
|
||||
sampler raw CSV is `UnrealEditor-Core.dll + RVA 0xC080` (runtime PCs around
|
||||
`0x7FF88382C080`), inside the private `.pdata` function range `0xB4D0–0xC32B`; the packaged Core
|
||||
binary has no PDB, so a source function name cannot be recovered here. Smaller unresolved groups
|
||||
map to generated engine reflection/CoreUObject code, not to `Plugins\VoxelForge`.
|
||||
- **Collision only at LOD0 (T1.c)** (`ApplyMeshToChunk`): `UpdateSectionConfig(..., LOD==0)`.
|
||||
LOD1/2 chunks are unreachable (the §8.10 reconciliation hot-swaps to LOD0 before the player
|
||||
arrives), so cooking their Chaos collision is waste. Don't force collision on for all LODs.
|
||||
|
||||
Reference in new issue
Block a user