perf(tunnels): memoise the room mouth -- room ownership now cheaper than before the change

The room-wins rule cost +55% static / +36% moving worker CPU because every sample re-answered the room-mouth question. A bounded exact memo around BuildRoomMouth (4096 sets x 4 ways, 7.49 MiB, keyed on every geometry-affecting room/tunnel input) removes that: hit rate 99.91% static / 99.89% moving, and VF_FindRoomFloorCrossingWorld (19.5%/17.1% inclusive), VF_FindRoomMouthBoundary (16.0%/14.0%) and VF_EvaluateRoomLandingDensity leave the sampler's top 30 entirely.

vs the tip DLL (bf9384a runtime), same staged owner map: worker sum 29.003 s vs 30.749 s static (-5.7%), 57.232 s vs 60.923 s moving (-6.1%), request p95 -3.3% / -8.4%. Geometry unchanged by construction: canonical hash 86A99075, 64/64 tile hashes, OBJ SHA 7E0D8109..C543, identical across a repeat run and with -voxel.CrtFma3=0. Walk Connected 42,870 / 17,413; tunnel-attributed solid inside rooms 0; mouth amplitude 1.4903 cm; TilePostReachProof and DetSinCos pass. The crossing test was not rerun (the memo returns the same values; its PASS stands at 248.43 m / 26.584 s).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5 committed 2026-09-18 03:41:38 +02:00
1 parent 76bc8bce97
commit 1c642fd182
5 files changed
+954 -135

No files matched your search

@@ -3747,6 +3747,8 @@ namespace
FTunnelCoreWorldEvaluation LastTunnelCoreWorldEvaluation;
FVector LastTunnelCoreEvaluationPosition = FVector::ZeroVector;
bool bLastTunnelCoreWorldEvaluationValid = false;
bool bLastRoomOwnsBottom = false;
bool bLastRoomOwnsBottomValid = false;
/** ÉTAPE C1 — les params de la strate avec l'op de CETTE salle appliqué par-dessus.
* Mémo par voxel : invalidé au début de chaque `Eval`, calculé au PREMIER modificateur
@@ -3800,6 +3802,7 @@ namespace
S.ActiveCache = Sample.RoomCache;
S.NearestRoom = Sample.NearestRoomIndex;
S.bLocalParamsValid = false;
S.bLastRoomOwnsBottomValid = false;
}
bool TryGetLastTunnelCoreWorldEvaluation(
@@ -3827,7 +3830,8 @@ namespace
S.LastTunnelCoreWorldEvaluation = VoxelCaveMorphology::EvaluateTunnelCoreWorld(
Position.X, Position.Y, Position.Z, GetCache(), nullptr,
VoxelGenLOD::ShouldUseSpatialIndex(false),
&S.LastWarpedPosition);
&S.LastWarpedPosition,
S.bLastRoomOwnsBottomValid ? &S.bLastRoomOwnsBottom : nullptr);
S.LastTunnelCoreEvaluationPosition = Position;
S.bLastTunnelCoreWorldEvaluationValid = true;
}
@@ -3922,6 +3926,7 @@ namespace
FState& S = State();
S.LastWorldPosition = FVector(WorldX, WorldY, WorldZ);
S.bLastTunnelCoreWorldEvaluationValid = false;
S.bLastRoomOwnsBottomValid = false;
// ⚠️ REMIS À -1 INCONDITIONNELLEMENT, ce que l'original ne fait pas : chez lui
// `NearestRoomIdx` est un `thread_local` qui, quand `RoomDensity <= 0`, garde la valeur
@@ -4184,7 +4189,9 @@ namespace
const FVector WorldTunnelPosition(WorldX, WorldY, WorldZ);
float CaveSDF = VoxelCaveMorphology::EvaluateSDFCached(
WarpedX, WarpedY, WarpedZ, GetCache(), P.SDFBlendRadius,
&S.NearestRoom, bUseSpatialIndex, &WorldTunnelPosition);
&S.NearestRoom, bUseSpatialIndex, &WorldTunnelPosition,
&S.bLastRoomOwnsBottom);
S.bLastRoomOwnsBottomValid = true;
//---------------------------------------------------------------
// PITS & CHEMINÉES — coordonnées RÉELLES, SmoothMin dans le même canal SDF
@@ -4275,7 +4282,8 @@ namespace
{
S.LastTunnelCoreWorldEvaluation = VoxelCaveMorphology::EvaluateTunnelCoreWorld(
WorldX, WorldY, WorldZ, GetCache(), nullptr,
bUseSpatialIndex, &S.LastWarpedPosition);
bUseSpatialIndex, &S.LastWarpedPosition,
&S.bLastRoomOwnsBottom);
S.LastTunnelCoreEvaluationPosition = S.LastWorldPosition;
S.bLastTunnelCoreWorldEvaluationValid = true;