measure(step2a): candidate bins alone are slower -- the per-sample GetDensityAt call must go

Editor-only ablation (explore commandlet, -regioneval, default off): 8^3 bins for rooms,
room-floor joins and tunnel chains, but every point still goes through GetDensityAt.
259^3 ring, seed 1337, six workers:
  live  : 6.776 s wall, 29.16 s worker CPU, 1.679 us/sample, 21.2 candidate visits/sample
  binned: 19.54 s wall, 50.02 s worker CPU, 2.879 us/sample, 16.4 candidate visits/sample
Correctness: zero Q16 (x16, ties away from zero) disagreements on the full ring and ~284k probes
on 4 more seeds (composer recipes, warped rooms, passages, landings, strate edges, edits);
shrinking room reach to 0.5 -> 18,107 Q16 / 735 sign differences (the check bites).
Not the planned region program: the step-2 question is still open. Baseline for the next attempt:
1.68 us CPU per sample on the live path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-09-30 01:19:11 +02:00
1 parent 3b4d6855fe
commit 41a9265ebd
8 files changed
+1693 -31

No files matched your search

+71 -12
View File
@@ -1,6 +1,6 @@
[CmdletBinding()]
param(
[ValidateSet('canonical', 'owner', 'probe', 'perf', 'visual-edit', 'visual-lod', 'visual-gap-walk', 'visual-gap-inject', 'dig-motion', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'parity', 'horizon', 'horizon-render', 'determinism', 'symbolize-stacks')]
[ValidateSet('canonical', 'owner', 'probe', 'perf', 'visual-edit', 'visual-lod', 'visual-gap-walk', 'visual-gap-inject', 'dig-motion', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'parity', 'horizon', 'horizon-render', 'determinism', 'symbolize-stacks', 'region-eval')]
[string]$Scenario = 'canonical',
[switch]$Build,
[switch]$EnableRender,
@@ -247,13 +247,30 @@ public static class VoxelForgeTestMemoryStatus {
}
function Assert-EnoughFreeMemory([string]$When) {
$status = New-Object VoxelForgeTestMemoryStatus+MEMORYSTATUSEX
if (-not [VoxelForgeTestMemoryStatus]::GlobalMemoryStatusEx($status)) {
throw "Could not query free physical memory before $When; refusing to launch."
}
$freeGiB = [double]$status.ullAvailPhys / 1GB
if ($freeGiB -lt 6.0) {
throw ("Only {0:N2} GiB free before {1}; refusing to launch (minimum 6 GiB)." -f $freeGiB, $When)
$deadline = [datetime]::UtcNow.AddMinutes(30)
$didWait = $false
while ($true) {
$status = New-Object VoxelForgeTestMemoryStatus+MEMORYSTATUSEX
if (-not [VoxelForgeTestMemoryStatus]::GlobalMemoryStatusEx($status)) {
throw "Could not query free physical memory before $When; refusing to launch."
}
$freeGiB = [double]$status.ullAvailPhys / 1GB
if ($freeGiB -ge 6.0) {
if ($didWait) {
Write-Host ("Free memory recovered to {0:N2} GiB before {1}; continuing." -f $freeGiB, $When)
}
Assert-NoForeignUnreal "$When after memory check"
return
}
if ([datetime]::UtcNow -ge $deadline) {
throw ("Free memory stayed at {0:N2} GiB before {1} for 30 minutes; refusing to launch." -f $freeGiB, $When)
}
if (-not $didWait) {
Write-Host ("Waiting for free memory: {0:N2} GiB before {1}; need at least 6.00 GiB." -f $freeGiB, $When)
$didWait = $true
}
Assert-NoForeignUnreal "$When while waiting for memory"
Start-Sleep -Seconds 15
}
}
@@ -551,7 +568,7 @@ function Sync-OwnerAssets {
$null = Copy-Item -LiteralPath $source -Destination $target -Force -PassThru
[void]$rows.Add([ordered]@{
name = $assetName
used_by_scenario = $Scenario -in @('owner', 'probe', 'parity', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'visual-edit', 'visual-lod', 'visual-gap-walk', 'visual-gap-inject', 'dig-motion', 'horizon', 'horizon-render', 'determinism')
used_by_scenario = $Scenario -in @('owner', 'probe', 'parity', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'visual-edit', 'visual-lod', 'visual-gap-walk', 'visual-gap-inject', 'dig-motion', 'horizon', 'horizon-render', 'determinism', 'region-eval')
source_path = $source
source_sha256 = Get-Sha256 $source
staged_path = $target
@@ -599,7 +616,7 @@ function Get-AssetEvidence {
$target = Join-Path $HostRoot "Content\VoxelForge\$assetName.uasset"
[void]$rows.Add([ordered]@{
name = $assetName
used_by_scenario = $Scenario -in @('owner', 'probe', 'parity', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'visual-edit', 'visual-lod', 'visual-gap-walk', 'visual-gap-inject', 'dig-motion', 'horizon', 'horizon-render', 'determinism')
used_by_scenario = $Scenario -in @('owner', 'probe', 'parity', 'tests', 'surface-fall', 'crossing', 'gate-stress', 'visual-edit', 'visual-lod', 'visual-gap-walk', 'visual-gap-inject', 'dig-motion', 'horizon', 'horizon-render', 'determinism', 'region-eval')
source_path = $source
source_sha256 = Get-Sha256 $source
staged_path = $target
@@ -1328,6 +1345,13 @@ try {
'-WaitMutex', '-FromMsBuild', '-architecture=x64', '-NoUBA', '-ForceHeaderGeneration', '-MaxParallelActions=4',
('-Log="{0}"' -f $buildLog))
$BuildRecord = Invoke-BuildProcess $buildArgs $buildLog $buildError $buildStdout
$ubtCompilerFailures = @(Select-String -LiteralPath $buildLog `
-Pattern 'Result:\s*Failed|error C\d+|fatal error C\d+' -ErrorAction SilentlyContinue |
Select-Object -First 20 | ForEach-Object { $_.Line.Trim() })
if ($ubtCompilerFailures.Count -gt 0) {
$BuildRecord.status = 'failed'
$BuildRecord.compiler_diagnostics = $ubtCompilerFailures
}
if ($BuildRecord.status -ne 'passed') { Add-Failure "staged build $($BuildRecord.status)" }
$runtimeAfter = Get-Sha256 (Join-Path $StagePlugin 'Binaries\Win64\UnrealEditor-VoxelForge.dll')
$editorAfter = Get-Sha256 (Join-Path $StagePlugin 'Binaries\Win64\UnrealEditor-VoxelForgeEditor.dll')
@@ -1338,12 +1362,15 @@ try {
$BuildRecord.editor_dll_after = $editorAfter
$runtimeChanged = @($sourceChangedKeys | Where-Object { $_ -like 'source\voxelforge\*' }).Count -gt 0
$editorChanged = @($sourceChangedKeys | Where-Object { $_ -like 'source\voxelforgeeditor\*' }).Count -gt 0
if ($runtimeChanged -and $runtimeBefore -eq $runtimeAfter) {
if ($BuildRecord.status -eq 'passed' -and $runtimeChanged -and $runtimeBefore -eq $runtimeAfter) {
throw 'Source changed under Source/VoxelForge but the staged runtime DLL SHA-256 did not change.'
}
if ($editorChanged -and $editorBefore -eq $editorAfter) {
if ($BuildRecord.status -eq 'passed' -and $editorChanged -and $editorBefore -eq $editorAfter) {
throw 'Source changed under Source/VoxelForgeEditor but the staged editor DLL SHA-256 did not change.'
}
if ($BuildRecord.status -ne 'passed') {
throw "Staged UBT build failed; skipping the region-eval commandlet. See $buildLog."
}
}
if ($Assets -eq 'owner') {
$AssetEvidence = @(Sync-OwnerAssets)
@@ -1398,6 +1425,36 @@ try {
(Join-Path $RunRoot 'Logs\probe.log') (Join-Path $RunRoot 'Logs\probe.stdout.log') (Join-Path $RunRoot 'Logs\probe.stderr.log')
$CommandletMetrics = Get-CommandletMetrics $commandletOut 'owner probe'
}
'region-eval' {
$regionLog = Join-Path $RunRoot 'Logs\region-eval.log'
$args = New-CommonArguments 'commandlet' $regionLog (Merge-Cvars $baseCvars)
$args += New-CommandletArguments $commandletOut 'walk,export' ($Assets -eq 'owner') $false 128
$args += @('-regioneval', '-regionsamples=262144')
$commandletLedger = Invoke-UnrealLaunch 'region-eval-commandlet' $args `
$regionLog (Join-Path $RunRoot 'Logs\region-eval.stdout.log') `
(Join-Path $RunRoot 'Logs\region-eval.stderr.log')
$regionReportPath = Join-Path $commandletOut 'region_eval.json'
$regionReport = Read-JsonFile $regionReportPath
if ($null -eq $regionReport) {
$CommandletMetrics = [ordered]@{
status = 'missing'
output = $commandletOut
report = $regionReportPath
}
Add-Failure "region-eval did not produce $regionReportPath"
} else {
$CommandletMetrics = [ordered]@{
status = if ((Get-JsonValue $regionReport 'pass' $false) -and $commandletLedger.status -eq 'passed') { 'correctness_pass' } else { 'failed' }
output = $commandletOut
report = $regionReportPath
speed_pass_600ms = Get-JsonValue $regionReport 'speed_pass_600ms' $false
result = $regionReport
}
if (-not (Get-JsonValue $regionReport 'pass' $false)) {
Add-Failure 'region-eval correctness, determinism, or deliberate reach-shrink gate failed'
}
}
}
'symbolize-stacks' {
if (([string]::IsNullOrWhiteSpace($StackSamplesPath)) -or -not (Test-Path -LiteralPath $StackSamplesPath -PathType Leaf)) {
throw "-StackSamplesPath must name an existing raw sampler CSV."
@@ -1802,6 +1859,7 @@ $result = [ordered]@{
obj_sha256 = if ($CommandletMetrics.Contains('obj_sha256')) { $CommandletMetrics.obj_sha256 } else { $null }
probe_amplitudes = if ($CommandletMetrics.Contains('probe_amplitudes')) { $CommandletMetrics.probe_amplitudes } else { [ordered]@{} }
commandlet = $CommandletMetrics
region_eval = if ($Scenario -eq 'region-eval') { $CommandletMetrics } else { $null }
game = $GameMetrics
horizon = $HorizonMetrics
horizon_render = $HorizonRenderMetrics
@@ -1842,6 +1900,7 @@ try {
[void]$summaryLines.Add("connectivity=$(ConvertTo-CompactJson $result.connectivity)")
[void]$summaryLines.Add("geometry_hash=$($result.geometry_hash)")
[void]$summaryLines.Add("obj_sha256=$($result.obj_sha256)")
[void]$summaryLines.Add("region_eval=$(ConvertTo-CompactJson $result.region_eval)")
[void]$summaryLines.Add("surface_fall=$(ConvertTo-CompactJson $result.surface_fall)")
[void]$summaryLines.Add("strate_crossing=$(ConvertTo-CompactJson $result.strate_crossing)")
[void]$summaryLines.Add("visual_staleness=$(ConvertTo-CompactJson $result.visual_staleness)")