measure(perf): per-component ablation of the TunnelNetwork path; exact worms restored
Round (Codex; reviewed by me against PERF-SAMPLED.md). Revert: voxel.WormNoiseMode / voxel.WormLatticeStep, their storage and their switches are REMOVED. VoxelWormField has one path again, exact Perlin with the N1 short circuit. Kept: bEnableWorms (asset), WormsForceOff (measurement only), the exact block skip (default 0). Ablation instrument: 14 development-only, world-changing force-off bits (voxel.TunnelAblate*), applied on the fused, op-stack/classifier, cached SDF/core and modifier/floor paths. They resolve once per process, are hashed into the generation fingerprint, and are compiled to zero in UE_BUILD_SHIPPING (VoxelDensityAblation.cpp). They are a measurement instrument, never a gameplay or multiplayer switch. Defaults exact: canonical export OBJ b3e5f4c3..9b377, worms-region 311CA42C / 75,482 triangles, capability 20,830 / 10,909, and 841/841 keyed tiles identical to NextHeadStaticTrace_20260913. Static worker seconds saved by removing ONE component (two off runs vs the interleaved all-on 33.06 s; baseline noise 0.27%): tunnel SDF 11.4%, cave warp 10.3%, passage carving 10.1%, landing posts 9.9%, passage structural posts 5.6%, worms 2.4%, native floor 2.2%, origin spine 1.6%, room SDF 1.6%, everything else <= 1.1% Moving (2+2 runs each) confirms the top five at 6.0-11.6%. Tunnel SDF off cuts LOD0 generation p95 104 -> 83 ms: it owns the slow tail. The positive savings sum to 58% of the static total; the other 42% is shared. The rows are not additive. Unexplained: tunnel-core OFF made the static total 2.9x SLOWER (95.5 s) while LOD0 generation got faster (p50 64.7 -> 60.6 ms) and triangles fell. The report blames the changed field, which does not fit; more likely a slow fallback path in coarse tiles. That row is not a cost measurement. Ledger: every Unreal process exited 0 and verified the loaded DLL; two PowerShell parser errors happened before any process started. No crashes or retries. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TaFdXhTdYMkW1xrV6ApT6Y
This commit is contained in:
1 parent
c132243b30
commit
6ccf3718ff
12 files changed
+833
-695
No files matched your search
@@ -0,0 +1,131 @@
|
||||
// VoxelDensityAblation.cpp
|
||||
// Development-only TunnelNetwork ablation controls.
|
||||
|
||||
#include "VoxelDensityAblation.h"
|
||||
|
||||
#include "HAL/IConsoleManager.h"
|
||||
#include "Misc/CommandLine.h"
|
||||
#include "Misc/Parse.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr uint32 UnresolvedMask = 0xFFFFFFFFu;
|
||||
std::atomic<uint32> GResolvedMask(UnresolvedMask);
|
||||
|
||||
#if !UE_BUILD_SHIPPING
|
||||
int32 GCaveWarp = 0;
|
||||
int32 GDetailOps = 0;
|
||||
int32 GRoomSDF = 0;
|
||||
int32 GTunnelSDF = 0;
|
||||
int32 GTunnelCore = 0;
|
||||
int32 GPassageCarving = 0;
|
||||
int32 GPassageStructuralPosts = 0;
|
||||
int32 GNativeFloor = 0;
|
||||
int32 GDisturbances = 0;
|
||||
int32 GOriginSpine = 0;
|
||||
int32 GBoundarySeal = 0;
|
||||
int32 GLandingPosts = 0;
|
||||
int32 GXYEdgeSeal = 0;
|
||||
int32 GPitChimneySDF = 0;
|
||||
|
||||
#define VF_ABLATION_CVAR(Name, Storage) \
|
||||
FAutoConsoleVariableRef CVar##Storage( \
|
||||
Name, Storage, \
|
||||
TEXT("WORLD-CHANGING DEVELOPMENT-ONLY measurement override. Forces this " \
|
||||
"TunnelNetwork density stage off; never use as a gameplay switch. " \
|
||||
"All peers and regenerated worlds must use the same value. Resolved once " \
|
||||
"per process. 0=on, 1=off."), ECVF_Default)
|
||||
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateCaveWarp"), GCaveWarp);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateDetailOps"), GDetailOps);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateRoomSDF"), GRoomSDF);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateTunnelSDF"), GTunnelSDF);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateTunnelCore"), GTunnelCore);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblatePassageCarving"), GPassageCarving);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblatePassageStructuralPosts"), GPassageStructuralPosts);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateNativeFloor"), GNativeFloor);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateDisturbances"), GDisturbances);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateOriginSpine"), GOriginSpine);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateBoundarySeal"), GBoundarySeal);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateLandingPosts"), GLandingPosts);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblateXYEdgeSeal"), GXYEdgeSeal);
|
||||
VF_ABLATION_CVAR(TEXT("voxel.TunnelAblatePitChimneySDF"), GPitChimneySDF);
|
||||
|
||||
#undef VF_ABLATION_CVAR
|
||||
|
||||
uint32 ResolveValue(const TCHAR* Name, int32& Storage)
|
||||
{
|
||||
int32 Value = Storage;
|
||||
FParse::Value(FCommandLine::Get(), Name, Value);
|
||||
Storage = Value != 0 ? 1 : 0;
|
||||
return Storage != 0 ? 1u : 0u;
|
||||
}
|
||||
|
||||
uint32 ResolveMask()
|
||||
{
|
||||
uint32 Mask = 0;
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateCaveWarp="), GCaveWarp)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::CaveWarp);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateDetailOps="), GDetailOps)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::DetailOps);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateRoomSDF="), GRoomSDF)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::RoomSDF);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateTunnelSDF="), GTunnelSDF)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::TunnelSDF);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateTunnelCore="), GTunnelCore)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::TunnelCore);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblatePassageCarving="), GPassageCarving)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::PassageCarving);
|
||||
Mask |= ResolveValue(
|
||||
TEXT("voxel.TunnelAblatePassageStructuralPosts="), GPassageStructuralPosts)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::PassageStructuralPosts);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateNativeFloor="), GNativeFloor)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::NativeFloor);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateDisturbances="), GDisturbances)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::Disturbances);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateOriginSpine="), GOriginSpine)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::OriginSpine);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateBoundarySeal="), GBoundarySeal)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::BoundarySeal);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateLandingPosts="), GLandingPosts)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::LandingPosts);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblateXYEdgeSeal="), GXYEdgeSeal)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::XYEdgeSeal);
|
||||
Mask |= ResolveValue(TEXT("voxel.TunnelAblatePitChimneySDF="), GPitChimneySDF)
|
||||
* static_cast<uint32>(VoxelDensityAblation::EStage::PitChimneySDF);
|
||||
return Mask;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace VoxelDensityAblation
|
||||
{
|
||||
uint32 GetResolvedMask()
|
||||
{
|
||||
uint32 Existing = GResolvedMask.load(std::memory_order_acquire);
|
||||
if (Existing != UnresolvedMask)
|
||||
{
|
||||
return Existing;
|
||||
}
|
||||
|
||||
#if UE_BUILD_SHIPPING
|
||||
constexpr uint32 Resolved = 0;
|
||||
#else
|
||||
const uint32 Resolved = ResolveMask();
|
||||
#endif
|
||||
uint32 Expected = UnresolvedMask;
|
||||
if (!GResolvedMask.compare_exchange_strong(
|
||||
Expected, Resolved, std::memory_order_release, std::memory_order_acquire))
|
||||
{
|
||||
return Expected;
|
||||
}
|
||||
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeTunnelAblation] resolved mask=0x%08x "
|
||||
"(world-changing development measurement overrides; 0=all on)"),
|
||||
Resolved);
|
||||
return Resolved;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user