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
@@ -206,8 +206,12 @@ private:
|
||||
// uphill). See SurfaceDensityFromColumn for the warped-terrain union that makes the shelf.
|
||||
struct FSurfaceColumn
|
||||
{
|
||||
float TerrainZ = 0.0f; float CeilSurf = 0.0f;
|
||||
float OverhangAmp = 0.0f; float DirX = 0.0f; float DirY = 0.0f;
|
||||
// Toutes les sorties sont écrites par ComputeSurfaceColumn avant Computed=true ; les valeurs
|
||||
// par défaut ne sont donc jamais lues et leur constructeur implicite coûte dans le TLS.
|
||||
// Every output is written by ComputeSurfaceColumn before Computed=true; the defaults are never
|
||||
// read, and removing them keeps FSurfaceColumn trivial so TLS construction has no leaf work.
|
||||
float TerrainZ, CeilSurf;
|
||||
float OverhangAmp, DirX, DirY;
|
||||
};
|
||||
|
||||
struct FSurfaceColumnBox
|
||||
@@ -2355,7 +2359,6 @@ float UVoxelGenerator::GetDensityAt(float WorldX, float WorldY, float WorldZ) co
|
||||
Result = GetMazeDensity(WorldX, WorldY, WorldZ, CP_Maze); break;
|
||||
case ECaveGeneratorType::SurfaceWorld:
|
||||
{
|
||||
FSurfaceColumn Col;
|
||||
// Integer XY (the density grid) → reuse the column down its whole Z extent (T1.a).
|
||||
// Fractional XY (gradient-normal samples) → compute directly (no cache key).
|
||||
if (WorldX == FMath::FloorToFloat(WorldX) && WorldY == FMath::FloorToFloat(WorldY))
|
||||
@@ -2373,17 +2376,20 @@ float UVoxelGenerator::GetDensityAt(float WorldX, float WorldY, float WorldZ) co
|
||||
Box.Cols[CI].OverhangAmp, Box.Cols[CI].DirX, Box.Cols[CI].DirY);
|
||||
Box.Computed[CI] = true;
|
||||
}
|
||||
Col = Box.Cols[CI];
|
||||
const FSurfaceColumn& Col = Box.Cols[CI];
|
||||
Result = SurfaceDensityFromColumn(WorldX, WorldY, WorldZ,
|
||||
Col.TerrainZ, Col.CeilSurf, Col.OverhangAmp,
|
||||
Col.DirX, Col.DirY, CP_Surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
float TerrainZ, CeilSurf, OverhangAmp, DirX, DirY;
|
||||
ComputeSurfaceColumn(WorldX, WorldY, ChunkCoord.Z, CP_Surface, CP_BiomeCtx,
|
||||
CP_SurfaceBiomeParams, CP_BiomeCache, Col.TerrainZ, Col.CeilSurf,
|
||||
Col.OverhangAmp, Col.DirX, Col.DirY);
|
||||
CP_SurfaceBiomeParams, CP_BiomeCache, TerrainZ, CeilSurf,
|
||||
OverhangAmp, DirX, DirY);
|
||||
Result = SurfaceDensityFromColumn(WorldX, WorldY, WorldZ,
|
||||
TerrainZ, CeilSurf, OverhangAmp, DirX, DirY, CP_Surface);
|
||||
}
|
||||
|
||||
Result = SurfaceDensityFromColumn(WorldX, WorldY, WorldZ,
|
||||
Col.TerrainZ, Col.CeilSurf, Col.OverhangAmp, Col.DirX, Col.DirY, CP_Surface);
|
||||
break;
|
||||
}
|
||||
case ECaveGeneratorType::VerticalShafts:
|
||||
|
||||
Reference in new issue
Block a user