perf(generation): inline exact IsFinite -- LOD0 ~11-12% faster, field-exact

The sampler's last "unknown" LOD0 bucket (~13.8%) was ucrtbase.dll!_finite: FMath::IsFinite is an
out-of-line CRT call on the MSVC game path, hit from the innermost tunnel, passage, density,
spatial-index and meshing loops.

- VoxelMath::IsFiniteFast(float/double) in VoxelTypes.h: memcpy to uint32/uint64,
  (Bits & ExpMask) != ExpMask. It is the same predicate for every bit pattern, with no FP
  comparison for fast-math to fold. The disassembly shows it inlined (movd/movq, mask, compare).
- VoxelMath::IsFinite routes through a plain global, voxel.FastIsFinite (default 1), for the A/B.
  The CRT call remains only on the switch-off branch. Hot generation-path uses are replaced; no
  _finite / std::isfinite remains in Source/VoxelForge. Tool/editor/test code keeps FMath.
- A test that can fail: VoxelForge.Math.IsFiniteExact compares against FMath::IsFinite over 22
  explicit float/double patterns (+-0, denormals, min/max normal, +-Inf, quiet and signalling NaN
  payloads) plus 2,000,000 hashed patterns each: 0 mismatches. The explicit NaNs make a NaN-wrong
  helper fail.

Field exact: 841/841 keyed tiles identical to NextHeadStaticTrace_20260913 (verdict/empty/
triangles), export OBJ unchanged (b3e5f4c3..9b377), capability 20,830 / 10,909.

Within-round A/B, game path, two interleaved runs each, sampler off (off -> on):
  static  LOD0 request p50  95.5 -> 84.8 ms   generation p50/p95  70.3/114.1 -> 62.3/100.6 ms
          worker            35.4 -> 31.6 s (-10.5%)
  moving  LOD0 request p50/p95  70.8/144.2 -> 62.0/126.1 ms
          generation p50/p95    62.6/113.4 -> 55.1/101.0 ms
          worker            102.6 -> 91.3 s (-11.0%)
Sampler-on moving: the _finite/CRT cluster is gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TaFdXhTdYMkW1xrV6ApT6Y
This commit is contained in:
Fr0zkaandClaude Opus 5 committed 2026-09-13 23:50:30 +02:00
1 parent 22186473f9
commit 5489b5e311
11 files changed
+816 -558

No files matched your search

+5 -5
View File
@@ -436,7 +436,7 @@ namespace
++OutMismatches;
}
const float Delta = (FMath::IsFinite(Live) && FMath::IsFinite(Reference))
const float Delta = (VoxelMath::IsFinite(Live) && VoxelMath::IsFinite(Reference))
? FMath::Abs(Live - Reference) : FLT_MAX;
OutMaxDelta = FMath::Max(OutMaxDelta, Delta);
++OutSamples;
@@ -1720,8 +1720,8 @@ bool AVoxelWorld::TryGetPlayerPosition(FVector& OutPosition, APawn** OutPawn) co
}
const FVector Position = Pawn->GetActorLocation();
if (!FMath::IsFinite(Position.X) || !FMath::IsFinite(Position.Y)
|| !FMath::IsFinite(Position.Z))
if (!VoxelMath::IsFinite(Position.X) || !VoxelMath::IsFinite(Position.Y)
|| !VoxelMath::IsFinite(Position.Z))
{
return false;
}
@@ -1766,7 +1766,7 @@ bool AVoxelWorld::GetPlayerSupportTile(APawn* Pawn, const FVector& PlayerPositio
Pawn->GetActorBounds(/*bOnlyCollidingComponents*/ true, BoundsOrigin, BoundsExtent);
HalfHeightCm = FMath::Max(0.0f, BoundsExtent.Z);
}
if (!FMath::IsFinite(HalfHeightCm))
if (!VoxelMath::IsFinite(HalfHeightCm))
{
return false;
}
@@ -4060,7 +4060,7 @@ void AVoxelWorld::GenerateTileResult(const FVoxelTileKey& Tile, const FIntVector
OriginVoxels.Y + Y * ValidationStep,
OriginVoxels.Z + Z * ValidationStep);
++Result.ValidationDensityCalls;
const bool bSampleAgrees = FMath::IsFinite(Density) && Density != 0.0f
const bool bSampleAgrees = VoxelMath::IsFinite(Density) && Density != 0.0f
&& (Verdict != EVoxelTileClass::AllSolid || Density < 0.0f)
&& (Verdict != EVoxelTileClass::AllAir || Density > 0.0f);
if (!bSampleAgrees)