perf(generation): per-tile reach test skips landing and structural posts -- ~12% less worker CPU
The remove-one ablation put landing posts at ~10% and passage structural posts at ~6% of worker time, though landings exist only near passage ends and the origin. The parked exact-cull round's per-SAMPLE post bounds had been a net loss. This round decides reach once per TILE (Codex; reviewed by me). - VoxelTilePostReach.h: one per-tile reach mask (thread-local byte), set when the tile is set up. The origin landing, passage landing SDF/floors, native floors, tunnel air and passage structural posts return their input unchanged on tiles no instance can reach. Per sample this costs an inline flag read. - Reach proofs come from each post's geometry (origin rooms, landing SDF and floors, native floor band, structural support spheres), not from comments. - voxel.TilePostReachDebug=1 evaluates the skipped posts anyway and compares the FINAL field; voxel.TilePostReachScale=0.5 deliberately shrinks the reach and must fail. Default build: 694 tiles, landing reachable on 4 (skipped on 690), structural posts skipped on 169. Soundness: 123,958,673 comparisons, 0 differences; shrunk reach: 13,929 differences, FAIL as required. Final DEFAULT build vs the committed-tip DLL (same command line, two interleaved runs each): static worker 34.80 -> 30.52 s (-12%) LOD0 generation p50/p95 67.0/107.6 -> 55.8/95.8 ms moving worker 75.96 -> 66.66 s (-12%) LOD0 generation p50/p95 66.3/106.0 -> 56.0/95.8 ms Field exact: 841/841 keyed tiles vs a fresh committed-tip trace (669,902 triangles, which includes 9260775's gap floors), export b3e5f4c3..9b377, capability 20,830 / 10,909; strate-crossing and sealed-proof tests pass. Ledger: all launches passed or failed where designed to; early raw-SDF debug attempts failed until the comparator was corrected to compare the final field. No crash folders. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TaFdXhTdYMkW1xrV6ApT6Y
This commit is contained in:
1 parent
92607751b1
commit
ce4d8783e9
7 files changed
+790
-20
No files matched your search
@@ -4,6 +4,8 @@
|
||||
#include "VoxelMarchingCubesMesher.h"
|
||||
#include "MarchingCubesTables.h"
|
||||
#include "VoxelDensityProfile.h"
|
||||
#include "VoxelStrateManager.h"
|
||||
#include "VoxelTilePostReach.h"
|
||||
#include "ProfilingDebugging/CpuProfilerTrace.h"
|
||||
#include "HAL/IConsoleManager.h"
|
||||
#include "Misc/CommandLine.h"
|
||||
@@ -17,6 +19,45 @@ namespace
|
||||
TEXT("Use the operator-major density block path for non-shared mesher grids."));
|
||||
bool GVoxelForgeBlockSwitchParsed = false;
|
||||
|
||||
int32 GVoxelForgeTilePostReachDebug = 0;
|
||||
FAutoConsoleVariableRef CVarVoxelForgeTilePostReachDebug(
|
||||
TEXT("voxel.TilePostReachDebug"),
|
||||
GVoxelForgeTilePostReachDebug,
|
||||
TEXT("Run skipped landing/structural posts in a bypass and compare their exact result; "
|
||||
"a nonzero difference fails the debug run."));
|
||||
|
||||
float GVoxelForgeTilePostReachScale = 1.0f;
|
||||
FAutoConsoleVariableRef CVarVoxelForgeTilePostReachScale(
|
||||
TEXT("voxel.TilePostReachScale"),
|
||||
GVoxelForgeTilePostReachScale,
|
||||
TEXT("Scale the per-tile post reach for deliberate soundness tests. Default 1.0 is exact; "
|
||||
"values below 1 intentionally shrink the guard."));
|
||||
|
||||
bool GVoxelForgeTilePostReachSwitchesParsed = false;
|
||||
|
||||
void VF_ParseTilePostReachSwitches()
|
||||
{
|
||||
if (GVoxelForgeTilePostReachSwitchesParsed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
GVoxelForgeTilePostReachSwitchesParsed = true;
|
||||
int32 DebugValue = GVoxelForgeTilePostReachDebug;
|
||||
float ScaleValue = GVoxelForgeTilePostReachScale;
|
||||
FParse::Value(
|
||||
FCommandLine::Get(), TEXT("voxel.TilePostReachDebug="), DebugValue);
|
||||
FParse::Value(
|
||||
FCommandLine::Get(), TEXT("voxel.TilePostReachScale="), ScaleValue);
|
||||
GVoxelForgeTilePostReachDebug = DebugValue != 0 ? 1 : 0;
|
||||
if (!VoxelMath::IsFinite(ScaleValue) || ScaleValue <= 0.0f)
|
||||
{
|
||||
ScaleValue = 1.0f;
|
||||
}
|
||||
GVoxelForgeTilePostReachScale = FMath::Min(ScaleValue, 1.0f);
|
||||
VoxelGenLOD::GTilePostReachDebugEnabled.store(
|
||||
GVoxelForgeTilePostReachDebug != 0, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void VF_ParseOperatorBlockSwitch()
|
||||
{
|
||||
if (GVoxelForgeBlockSwitchParsed) { return; }
|
||||
@@ -42,6 +83,7 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
{
|
||||
TRACE_CPUPROFILER_EVENT_SCOPE(VoxelForge_MesherGenerateMesh);
|
||||
VF_ParseOperatorBlockSwitch();
|
||||
VF_ParseTilePostReachSwitches();
|
||||
FVoxelMeshData MeshData;
|
||||
if (OutCaptureGrid) { OutCaptureGrid->Reset(); }
|
||||
if (OutDensitySampleCount) { *OutDensitySampleCount = 0; }
|
||||
@@ -233,6 +275,49 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
||||
VoxelGenLOD::TileOriginVoxels, OriginVoxels);
|
||||
TGuardValue<int32> TileCellsGuard(
|
||||
VoxelGenLOD::TileCellsPerAxis, CellsPerAxis);
|
||||
|
||||
// Every density sample in this tile sees the same post-reach decision. The one-point halo
|
||||
// matches the actual grid fill below (gx/gy/gz = -1..GridDim), so a false bit proves that no
|
||||
// landing or passage structural writer can reach any sample used by meshing or gradients.
|
||||
TGuardValue<bool> TilePostReachDebugGuard(
|
||||
VoxelGenLOD::bTilePostReachDebug,
|
||||
GVoxelForgeTilePostReachDebug != 0);
|
||||
TGuardValue<bool> TilePostReachBypassGuard(
|
||||
VoxelGenLOD::bTilePostReachBypass, false);
|
||||
uint8 TilePostReachFlags = VoxelGenLOD::AllTilePostReach;
|
||||
if (Generator->StrateManager != nullptr)
|
||||
{
|
||||
const int64 Extent = static_cast<int64>(CellsPerAxis + 1) * Step;
|
||||
const FBox LatticeWithHalo(
|
||||
FVector(
|
||||
static_cast<float>(static_cast<int64>(OriginVoxels.X) - Step),
|
||||
static_cast<float>(static_cast<int64>(OriginVoxels.Y) - Step),
|
||||
static_cast<float>(static_cast<int64>(OriginVoxels.Z) - Step)),
|
||||
FVector(
|
||||
static_cast<float>(static_cast<int64>(OriginVoxels.X) + Extent),
|
||||
static_cast<float>(static_cast<int64>(OriginVoxels.Y) + Extent),
|
||||
static_cast<float>(static_cast<int64>(OriginVoxels.Z) + Extent)));
|
||||
const float ReachScale = GVoxelForgeTilePostReachScale;
|
||||
TilePostReachFlags = 0;
|
||||
if (Generator->StrateManager->AnyOriginLandingNearLattice(
|
||||
LatticeWithHalo, OriginVoxels, Step, ReachScale))
|
||||
{
|
||||
TilePostReachFlags |= VoxelGenLOD::OriginLandingReachable;
|
||||
}
|
||||
if (Generator->StrateManager->AnyPassageLandingNearLattice(
|
||||
LatticeWithHalo, OriginVoxels, Step, ReachScale))
|
||||
{
|
||||
TilePostReachFlags |= VoxelGenLOD::PassageLandingReachable;
|
||||
}
|
||||
if (Generator->StrateManager->AnyPassageStructuralPostNearLattice(
|
||||
LatticeWithHalo, OriginVoxels, Step, ReachScale))
|
||||
{
|
||||
TilePostReachFlags |= VoxelGenLOD::PassageStructuralReachable;
|
||||
}
|
||||
}
|
||||
TGuardValue<uint8> TilePostReachFlagsGuard(
|
||||
VoxelGenLOD::TilePostReachFlags, TilePostReachFlags);
|
||||
VoxelGenLOD::RecordTileReachMask(TilePostReachFlags);
|
||||
// COUPE DE CONTENU PAR STRATE — restreint le maillage (et l'échantillonnage) aux cellules
|
||||
// dont l'intervalle Z chevauche la bande [BandZMinVox, BandZMaxVox] (voxels inclusifs).
|
||||
// Les tuiles à capture ne sont jamais bandées (niveau 0 — garde-fou ci-dessous).
|
||||
|
||||
Reference in new issue
Block a user