measure(step2c): setup once per chunk, still 1.6 us/sample -- exact per-sample density misses 600 ms
Editor-only, default off. 259^3 ring split into 1,000 aligned 32^3 chunks; cache/index builds bounded by chunks (948 room/SDF caches, 800 active-op lists, 8,532 index tables); 800 block setups + 201,243 scalar fallback points (1.16%); no per-point GetDensityAt on supported routes. Six workers: live 7.07 s wall / 1.678 us per sample; prepared 7.92 s / 1.595 us. Candidate visits 21.2 -> 15.8 per sample, evaluations 6.31 -> 5.75; room / tunnel / tunnel-core evaluations unchanged (48.1 M / 5.0 M / 38.4 M for 17.4 M samples). Passage evals 18.1 M -> 8.4 M. Exact: 0 Q16/sign disagreements, five seeds, same hash on 1 and 6 workers, reach shrink caught. Luna's verdict: 600 ms is not reachable while every lattice point evaluates the exact current density; 27.7 worker-CPU seconds need >= 7.7x less work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
1 parent
fd9f809c1c
commit
43c11ccaa8
9 files changed
+484
-143
No files matched your search
@@ -1758,7 +1758,7 @@ bool RunRegionEvalPass(
|
||||
const FExploreArguments& BaseArguments,
|
||||
int32 Seed,
|
||||
bool bPrepared,
|
||||
bool bBrickProgram,
|
||||
bool bRegionProgram,
|
||||
float ReachScale,
|
||||
bool bFullRing,
|
||||
const TArray<int64>* RequestedIndices,
|
||||
@@ -1767,7 +1767,8 @@ bool RunRegionEvalPass(
|
||||
bool bKeepDensities,
|
||||
FRegionEvalPass& OutPass,
|
||||
FString& OutError,
|
||||
int32 RequestedWorkerCount = VoxelForgeRegionEval::WorkerCount)
|
||||
int32 RequestedWorkerCount = VoxelForgeRegionEval::WorkerCount,
|
||||
bool bCollectWholeRunCounters = false)
|
||||
{
|
||||
OutPass = FRegionEvalPass();
|
||||
FExploreWorld World;
|
||||
@@ -1809,7 +1810,7 @@ bool RunRegionEvalPass(
|
||||
bFullRing ? nullptr : &OutPass.SampleIndices,
|
||||
bFullRing, bPrepared, ReachScale,
|
||||
bKeepDensities ? &OutPass.Densities : nullptr,
|
||||
OutPass.Timing, bBrickProgram, RequestedWorkerCount);
|
||||
OutPass.Timing, bRegionProgram, RequestedWorkerCount, bCollectWholeRunCounters);
|
||||
OutPass.EndedUtc = FDateTime::UtcNow().ToIso8601();
|
||||
if (!bEvaluated)
|
||||
{
|
||||
@@ -1835,18 +1836,102 @@ bool RunRegionEvalPass(
|
||||
TSharedRef<FJsonObject> RegionEvalTimingJson(const FRegionEvalPass& Pass, bool bPrepared)
|
||||
{
|
||||
TSharedRef<FJsonObject> Json = MakeShared<FJsonObject>();
|
||||
Json->SetStringField(TEXT("path"), Pass.Timing.bBrickProgram
|
||||
? TEXT("editor_region_brick_program")
|
||||
Json->SetStringField(TEXT("path"), Pass.Timing.bRegionProgram
|
||||
? TEXT("editor_region_chunk_program")
|
||||
: (bPrepared ? TEXT("prepared_8cube_bins") : TEXT("live_GetDensityAt")));
|
||||
Json->SetStringField(TEXT("started_utc"), Pass.StartedUtc);
|
||||
Json->SetStringField(TEXT("ended_utc"), Pass.EndedUtc);
|
||||
Json->SetNumberField(TEXT("worker_count"), Pass.Timing.Workers);
|
||||
Json->SetNumberField(TEXT("observed_worker_threads"), Pass.Timing.ObservedWorkerThreads);
|
||||
Json->SetNumberField(TEXT("samples"), static_cast<double>(Pass.Timing.SampleCount));
|
||||
Json->SetNumberField(TEXT("evaluated_brick_points"), static_cast<double>(Pass.Timing.EvaluatedSamples));
|
||||
Json->SetNumberField(TEXT("brick_count"), static_cast<double>(Pass.Timing.BrickCount));
|
||||
Json->SetNumberField(TEXT("evaluated_points"), static_cast<double>(Pass.Timing.EvaluatedSamples));
|
||||
Json->SetNumberField(TEXT("region_count"), static_cast<double>(Pass.Timing.RegionCount));
|
||||
Json->SetNumberField(TEXT("fallback_points"), static_cast<double>(Pass.Timing.FallbackSamples));
|
||||
Json->SetNumberField(TEXT("fallback_share"), Pass.Timing.FallbackShare);
|
||||
Json->SetNumberField(TEXT("general_path_entries"), static_cast<double>(Pass.Timing.GeneralPathEntries));
|
||||
Json->SetNumberField(TEXT("general_path_entries_per_evaluated_sample"),
|
||||
Pass.Timing.GeneralPathEntriesPerSample);
|
||||
Json->SetNumberField(TEXT("supported_block_setup_entries"),
|
||||
static_cast<double>(Pass.Timing.SupportedBlockSetupEntries));
|
||||
Json->SetBoolField(TEXT("whole_run_counters_present"), Pass.Timing.bHasWholeRunCounters);
|
||||
if (Pass.Timing.bHasWholeRunCounters)
|
||||
{
|
||||
Json->SetNumberField(TEXT("room_graph_sdf_cache_builds"),
|
||||
static_cast<double>(Pass.Timing.SdfCacheBuilds));
|
||||
Json->SetNumberField(TEXT("active_op_list_builds"),
|
||||
static_cast<double>(Pass.Timing.ActiveOpListBuilds));
|
||||
Json->SetNumberField(TEXT("broad_phase_index_builds"),
|
||||
static_cast<double>(Pass.Timing.BroadPhaseIndexBuilds));
|
||||
Json->SetNumberField(TEXT("sdf_spatial_index_builds"),
|
||||
static_cast<double>(Pass.Timing.SdfSpatialIndexBuilds));
|
||||
Json->SetNumberField(TEXT("sdf_3d_brick_index_builds"),
|
||||
static_cast<double>(Pass.Timing.SdfBrickIndexBuilds));
|
||||
Json->SetNumberField(TEXT("candidate_visits_total"),
|
||||
static_cast<double>(Pass.Timing.TotalCandidateVisits));
|
||||
Json->SetNumberField(TEXT("candidate_visits_per_sample"),
|
||||
Pass.Timing.CandidateVisitsPerSample);
|
||||
Json->SetNumberField(TEXT("candidate_evaluations_total"),
|
||||
static_cast<double>(Pass.Timing.TotalCandidateEvaluations));
|
||||
Json->SetNumberField(TEXT("candidate_evaluations_per_sample"),
|
||||
Pass.Timing.CandidateEvaluationsPerSample);
|
||||
Json->SetNumberField(TEXT("room_candidate_visits"),
|
||||
static_cast<double>(Pass.Timing.RoomCandidateVisits));
|
||||
Json->SetNumberField(TEXT("room_evaluations"),
|
||||
static_cast<double>(Pass.Timing.RoomEvaluations));
|
||||
Json->SetNumberField(TEXT("tunnel_candidate_visits"),
|
||||
static_cast<double>(Pass.Timing.TunnelCandidateVisits));
|
||||
Json->SetNumberField(TEXT("tunnel_evaluations"),
|
||||
static_cast<double>(Pass.Timing.TunnelEvaluations));
|
||||
Json->SetNumberField(TEXT("tunnel_core_candidate_visits"),
|
||||
static_cast<double>(Pass.Timing.TunnelCoreCandidateVisits));
|
||||
Json->SetNumberField(TEXT("tunnel_core_evaluations"),
|
||||
static_cast<double>(Pass.Timing.TunnelCoreEvaluations));
|
||||
Json->SetNumberField(TEXT("passage_candidate_visits"),
|
||||
static_cast<double>(Pass.Timing.PassageCandidateVisits));
|
||||
Json->SetNumberField(TEXT("passage_evaluations"),
|
||||
static_cast<double>(Pass.Timing.PassageEvaluations));
|
||||
|
||||
TSharedRef<FJsonObject> Attribution = MakeShared<FJsonObject>();
|
||||
Attribution->SetNumberField(TEXT("get_density_at_ns_per_sample"),
|
||||
Pass.Timing.GetDensityAtNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("operator_block_ns_per_sample"),
|
||||
Pass.Timing.OperatorBlockNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("room_graph_source_ns_per_sample"),
|
||||
Pass.Timing.RoomGraphSourceNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("room_graph_build_ns_per_sample"),
|
||||
Pass.Timing.RoomGraphBuildNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("room_graph_sdf_ns_per_sample"),
|
||||
Pass.Timing.RoomGraphSdfNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("fused_evaluator_ns_per_sample"),
|
||||
Pass.Timing.FusedEvaluatorNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("tunnel_core_sdf_ns_per_sample"),
|
||||
Pass.Timing.TunnelCoreSdfNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("tunnel_core_world_ns_per_sample"),
|
||||
Pass.Timing.TunnelCoreWorldNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("tunnel_core_posts_ns_per_sample"),
|
||||
Pass.Timing.TunnelCorePostsNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("passage_modifier_ns_per_sample"),
|
||||
Pass.Timing.PassageModifierNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("passage_structural_posts_ns_per_sample"),
|
||||
Pass.Timing.PassageStructuralPostsNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("passage_floor_ns_per_sample"),
|
||||
Pass.Timing.PassageFloorNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("structural_posts_ns_per_sample"),
|
||||
Pass.Timing.StructuralPostsNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("density_prologue_ns_per_sample"),
|
||||
Pass.Timing.DensityPrologueNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("density_core_ns_per_sample"),
|
||||
Pass.Timing.DensityCoreNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("disturbances_ns_per_sample"),
|
||||
Pass.Timing.DisturbancesNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("boundary_seal_ns_per_sample"),
|
||||
Pass.Timing.DensityBoundarySealNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("diff_layer_ns_per_sample"),
|
||||
Pass.Timing.DiffLayerNsPerSample);
|
||||
Attribution->SetNumberField(TEXT("density_tail_ns_per_sample"),
|
||||
Pass.Timing.DensityTailNsPerSample);
|
||||
Json->SetObjectField(TEXT("fresh_attribution"), Attribution);
|
||||
}
|
||||
Json->SetNumberField(TEXT("world_setup_seconds_before_density_ring"), Pass.WorldPrepareSeconds);
|
||||
Json->SetNumberField(TEXT("wall_seconds"), Pass.Timing.WallSeconds);
|
||||
Json->SetNumberField(TEXT("worker_cpu_seconds"), Pass.Timing.WorkerCpuSeconds);
|
||||
@@ -1864,26 +1949,31 @@ TSharedRef<FJsonObject> RegionEvalTimingJson(const FRegionEvalPass& Pass, bool b
|
||||
Json->SetNumberField(TEXT("non_finite_samples"), static_cast<double>(Pass.Timing.NonFiniteSamples));
|
||||
if (Pass.Visits.SampleCount > 0)
|
||||
{
|
||||
Json->SetNumberField(TEXT("candidate_visits_per_sample"), Pass.Visits.PerSample);
|
||||
Json->SetNumberField(TEXT("room_candidate_visits"), static_cast<double>(Pass.Visits.Room));
|
||||
Json->SetNumberField(TEXT("tunnel_candidate_visits"), static_cast<double>(Pass.Visits.Tunnel));
|
||||
Json->SetNumberField(TEXT("tunnel_core_candidate_visits"), static_cast<double>(Pass.Visits.TunnelCore));
|
||||
Json->SetNumberField(TEXT("passage_candidate_visits"), static_cast<double>(Pass.Visits.Passage));
|
||||
Json->SetNumberField(TEXT("tunnel_cache_lookups"), static_cast<double>(Pass.Visits.TunnelCacheLookups));
|
||||
Json->SetNumberField(TEXT("tunnel_cache_hits"), static_cast<double>(Pass.Visits.TunnelCacheHits));
|
||||
Json->SetNumberField(TEXT("tunnel_cache_misses"), static_cast<double>(Pass.Visits.TunnelCacheMisses));
|
||||
Json->SetNumberField(TEXT("sdf_cache_builds"), static_cast<double>(Pass.Visits.SdfCacheBuilds));
|
||||
Json->SetNumberField(TEXT("candidate_counter_samples"), static_cast<double>(Pass.Visits.SampleCount));
|
||||
Json->SetNumberField(TEXT("attribution_sample_interval"), Pass.Visits.AttributionSampleInterval);
|
||||
Json->SetStringField(TEXT("attribution_basis"), TEXT("sampled VoxelDensityProfile phases; diagnostic only, excluded from clean timing"));
|
||||
Json->SetNumberField(TEXT("get_density_at_attributed_ns_per_sample"), Pass.Visits.GetDensityAtAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("density_prologue_attributed_ns_per_sample"), Pass.Visits.DensityPrologueAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("density_core_attributed_ns_per_sample"), Pass.Visits.DensityCoreAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("density_disturbances_attributed_ns_per_sample"), Pass.Visits.DensityDisturbancesAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("density_structural_posts_attributed_ns_per_sample"), Pass.Visits.DensityStructuralPostsAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("density_boundary_seal_attributed_ns_per_sample"), Pass.Visits.DensityBoundarySealAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("density_diff_layer_attributed_ns_per_sample"), Pass.Visits.DensityDiffLayerAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("density_tail_attributed_ns_per_sample"), Pass.Visits.DensityTailAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("probe_candidate_visits_per_sample"), Pass.Visits.PerSample);
|
||||
Json->SetNumberField(TEXT("probe_candidate_evaluations_per_sample"), Pass.Visits.EvaluatedPerSample);
|
||||
Json->SetNumberField(TEXT("probe_room_candidate_visits"), static_cast<double>(Pass.Visits.Room));
|
||||
Json->SetNumberField(TEXT("probe_room_candidate_evaluations"), static_cast<double>(Pass.Visits.RoomEvaluated));
|
||||
Json->SetNumberField(TEXT("probe_tunnel_candidate_visits"), static_cast<double>(Pass.Visits.Tunnel));
|
||||
Json->SetNumberField(TEXT("probe_tunnel_candidate_evaluations"), static_cast<double>(Pass.Visits.TunnelEvaluated));
|
||||
Json->SetNumberField(TEXT("probe_tunnel_core_candidate_visits"), static_cast<double>(Pass.Visits.TunnelCore));
|
||||
Json->SetNumberField(TEXT("probe_tunnel_core_candidate_evaluations"), static_cast<double>(Pass.Visits.TunnelCoreEvaluated));
|
||||
Json->SetNumberField(TEXT("probe_passage_candidate_visits"), static_cast<double>(Pass.Visits.Passage));
|
||||
Json->SetNumberField(TEXT("probe_passage_candidate_evaluations"), static_cast<double>(Pass.Visits.PassageEvaluated));
|
||||
Json->SetNumberField(TEXT("probe_tunnel_cache_lookups"), static_cast<double>(Pass.Visits.TunnelCacheLookups));
|
||||
Json->SetNumberField(TEXT("probe_tunnel_cache_hits"), static_cast<double>(Pass.Visits.TunnelCacheHits));
|
||||
Json->SetNumberField(TEXT("probe_tunnel_cache_misses"), static_cast<double>(Pass.Visits.TunnelCacheMisses));
|
||||
Json->SetNumberField(TEXT("probe_sdf_cache_builds"), static_cast<double>(Pass.Visits.SdfCacheBuilds));
|
||||
Json->SetNumberField(TEXT("probe_candidate_counter_samples"), static_cast<double>(Pass.Visits.SampleCount));
|
||||
Json->SetNumberField(TEXT("probe_attribution_sample_interval"), Pass.Visits.AttributionSampleInterval);
|
||||
Json->SetStringField(TEXT("probe_attribution_basis"), TEXT("sampled VoxelDensityProfile phases; diagnostic only, excluded from clean timing"));
|
||||
Json->SetNumberField(TEXT("probe_get_density_at_attributed_ns_per_sample"), Pass.Visits.GetDensityAtAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("probe_density_prologue_attributed_ns_per_sample"), Pass.Visits.DensityPrologueAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("probe_density_core_attributed_ns_per_sample"), Pass.Visits.DensityCoreAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("probe_density_disturbances_attributed_ns_per_sample"), Pass.Visits.DensityDisturbancesAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("probe_density_structural_posts_attributed_ns_per_sample"), Pass.Visits.DensityStructuralPostsAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("probe_density_boundary_seal_attributed_ns_per_sample"), Pass.Visits.DensityBoundarySealAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("probe_density_diff_layer_attributed_ns_per_sample"), Pass.Visits.DensityDiffLayerAttributedNsPerSample);
|
||||
Json->SetNumberField(TEXT("probe_density_tail_attributed_ns_per_sample"), Pass.Visits.DensityTailAttributedNsPerSample);
|
||||
}
|
||||
return Json;
|
||||
}
|
||||
@@ -2018,7 +2108,7 @@ int32 RunRegionEval(const FString& Params)
|
||||
ProbeReport->SetNumberField(TEXT("observed_worker_threads"),
|
||||
WorkerHashPass.Timing.ObservedWorkerThreads);
|
||||
ProbeReport->SetNumberField(TEXT("samples"), WorkerHashPass.Timing.SampleCount);
|
||||
ProbeReport->SetNumberField(TEXT("brick_count"), WorkerHashPass.Timing.BrickCount);
|
||||
ProbeReport->SetNumberField(TEXT("region_count"), WorkerHashPass.Timing.RegionCount);
|
||||
ProbeReport->SetNumberField(TEXT("fallback_points"), WorkerHashPass.Timing.FallbackSamples);
|
||||
ProbeReport->SetNumberField(TEXT("fallback_share"), WorkerHashPass.Timing.FallbackShare);
|
||||
ProbeReport->SetNumberField(TEXT("wall_seconds"), WorkerHashPass.Timing.WallSeconds);
|
||||
@@ -2064,6 +2154,8 @@ int32 RunRegionEval(const FString& Params)
|
||||
TArray<TSharedPtr<FJsonValue>> SeedReports;
|
||||
TArray<TSharedPtr<FJsonValue>> OldTimingReports;
|
||||
TArray<TSharedPtr<FJsonValue>> PreparedTimingReports;
|
||||
TSharedPtr<FJsonObject> LiveFullRingDiagnostics;
|
||||
TSharedPtr<FJsonObject> PreparedFullRingDiagnostics;
|
||||
TArray<float> OldFullDensities;
|
||||
TArray<float> PreparedFullDensities;
|
||||
TArray<int64> PrimarySampleIndices;
|
||||
@@ -2164,42 +2256,69 @@ int32 RunRegionEval(const FString& Params)
|
||||
&& OldFullSaturatedSamples == 0
|
||||
&& PreparedFullSaturatedSamples == 0;
|
||||
|
||||
// Exact whole-ring counters and sampled phase attribution are collected in separate cold
|
||||
// passes. Their diagnostic hooks stay out of the two wall-time trials used for the 600 ms bar.
|
||||
FRegionEvalPass LiveDiagnosticPass;
|
||||
if (!RunRegionEvalPass(
|
||||
Arguments, Seeds[0], false, false, 1.0f, true, nullptr,
|
||||
RequestedSamples, false, false, LiveDiagnosticPass, Error,
|
||||
VoxelForgeRegionEval::WorkerCount, true))
|
||||
{
|
||||
UE_LOG(LogTemp, Error,
|
||||
TEXT("[VoxelForgeRegionEval] live full-ring diagnostic pass failed: %s"), *Error);
|
||||
return 2;
|
||||
}
|
||||
LiveFullRingDiagnostics = RegionEvalTimingJson(LiveDiagnosticPass, false);
|
||||
CollectGarbage(GARBAGE_COLLECTION_KEEPFLAGS);
|
||||
FRegionEvalPass PreparedDiagnosticPass;
|
||||
if (!RunRegionEvalPass(
|
||||
Arguments, Seeds[0], true, true, 1.0f, true, nullptr,
|
||||
RequestedSamples, false, false, PreparedDiagnosticPass, Error,
|
||||
VoxelForgeRegionEval::WorkerCount, true))
|
||||
{
|
||||
UE_LOG(LogTemp, Error,
|
||||
TEXT("[VoxelForgeRegionEval] prepared full-ring diagnostic pass failed: %s"), *Error);
|
||||
return 2;
|
||||
}
|
||||
PreparedFullRingDiagnostics = RegionEvalTimingJson(PreparedDiagnosticPass, true);
|
||||
CollectGarbage(GARBAGE_COLLECTION_KEEPFLAGS);
|
||||
|
||||
// Statistical fixed-lattice comparisons across four additional independent seeds. The sample
|
||||
// set is a deterministic affine permutation of the entire 259^3 ring plus dense strata,
|
||||
// passage-floor, landing, carve, and fill probes.
|
||||
if (Arguments.bSampleStacks)
|
||||
{
|
||||
FRegionEvalStackSamplerSession BrickStackSamplerSession;
|
||||
if (!BrickStackSamplerSession.Start(
|
||||
FRegionEvalStackSamplerSession RegionStackSamplerSession;
|
||||
if (!RegionStackSamplerSession.Start(
|
||||
Arguments.SampleStacksIntervalUs, Arguments.OutDirectory,
|
||||
TEXT("region_eval_brick_ring")))
|
||||
TEXT("region_eval_chunk_ring")))
|
||||
{
|
||||
UE_LOG(LogTemp, Error,
|
||||
TEXT("[VoxelForgeRegionEval] brick stack sampler could not be started."));
|
||||
TEXT("[VoxelForgeRegionEval] chunk stack sampler could not be started."));
|
||||
return 2;
|
||||
}
|
||||
FRegionEvalPass ProfiledBrickPass;
|
||||
FRegionEvalPass ProfiledRegionPass;
|
||||
if (!RunRegionEvalPass(
|
||||
Arguments, Seeds[0], true, true, 1.0f, true, nullptr,
|
||||
RequestedSamples, false, false, ProfiledBrickPass, Error))
|
||||
RequestedSamples, false, false, ProfiledRegionPass, Error))
|
||||
{
|
||||
UE_LOG(LogTemp, Error,
|
||||
TEXT("[VoxelForgeRegionEval] brick attribution run failed: %s"), *Error);
|
||||
TEXT("[VoxelForgeRegionEval] chunk attribution run failed: %s"), *Error);
|
||||
return 2;
|
||||
}
|
||||
FVoxelStackSampler::FSummary BrickStackSummary;
|
||||
if (!BrickStackSamplerSession.Stop(BrickStackSummary))
|
||||
FVoxelStackSampler::FSummary RegionStackSummary;
|
||||
if (!RegionStackSamplerSession.Stop(RegionStackSummary))
|
||||
{
|
||||
UE_LOG(LogTemp, Error,
|
||||
TEXT("[VoxelForgeRegionEval] brick stack capture retained no worker samples."));
|
||||
TEXT("[VoxelForgeRegionEval] chunk stack capture retained no worker samples."));
|
||||
return 2;
|
||||
}
|
||||
UE_LOG(LogTemp, Display,
|
||||
TEXT("[VoxelForgeRegionEval] brick stack capture registered=%llu retained=%llu "
|
||||
TEXT("[VoxelForgeRegionEval] chunk stack capture registered=%llu retained=%llu "
|
||||
"raw=%s summary=%s"),
|
||||
static_cast<unsigned long long>(BrickStackSummary.RegisteredThreadSamples),
|
||||
static_cast<unsigned long long>(BrickStackSummary.RetainedSamples),
|
||||
*BrickStackSummary.RawSamplesPath, *BrickStackSummary.SummaryPath);
|
||||
static_cast<unsigned long long>(RegionStackSummary.RegisteredThreadSamples),
|
||||
static_cast<unsigned long long>(RegionStackSummary.RetainedSamples),
|
||||
*RegionStackSummary.RawSamplesPath, *RegionStackSummary.SummaryPath);
|
||||
}
|
||||
|
||||
for (int32 SeedIndex = 1; SeedIndex < UE_ARRAY_COUNT(Seeds); ++SeedIndex)
|
||||
@@ -2307,9 +2426,11 @@ int32 RunRegionEval(const FString& Params)
|
||||
const bool bSpeedPass = PreparedMedianWall <= 0.600 && bSixWorkersObserved;
|
||||
|
||||
TSharedRef<FJsonObject> Report = MakeShared<FJsonObject>();
|
||||
Report->SetNumberField(TEXT("schema_version"), 1);
|
||||
Report->SetNumberField(TEXT("schema_version"), 2);
|
||||
Report->SetStringField(TEXT("route"), TEXT("editor-only explore commandlet; required Unreal composer, manager, and generator types"));
|
||||
Report->SetStringField(TEXT("evaluator"), TEXT("editor-only 8^3 region brick program; block-evaluated composer operator core and canonical per-point final-field writers; unsupported routes use counted live fallbacks"));
|
||||
Report->SetStringField(TEXT("evaluator"), TEXT("editor-only chunk program; region-scoped room/SDF caches, one operator block per chunk, canonical post-stack writers, and counted live point fallbacks"));
|
||||
Report->SetStringField(TEXT("timing_basis"), TEXT("two cold wall-time trials per path with counters disabled; exact whole-ring counters and sampled phase attribution are separate diagnostic passes"));
|
||||
Report->SetBoolField(TEXT("diagnostic_passes_excluded_from_speed_verdict"), true);
|
||||
Report->SetStringField(TEXT("comparison_quantization"), TEXT("signed int16; round ties away from zero; multiply density by 16; saturate outside [-2048, 2047.9375] density voxels"));
|
||||
Report->SetNumberField(TEXT("worker_count"), VoxelForgeRegionEval::WorkerCount);
|
||||
Report->SetNumberField(TEXT("ring_dimension"), VoxelForgeRegionEval::RingDimension);
|
||||
@@ -2325,6 +2446,8 @@ int32 RunRegionEval(const FString& Params)
|
||||
Report->SetObjectField(TEXT("full_ring_comparison"), RegionEvalComparisonJson(FullComparison));
|
||||
Report->SetArrayField(TEXT("live_full_ring_trials"), OldTimingReports);
|
||||
Report->SetArrayField(TEXT("prepared_full_ring_trials"), PreparedTimingReports);
|
||||
Report->SetObjectField(TEXT("live_full_ring_diagnostics"), LiveFullRingDiagnostics.ToSharedRef());
|
||||
Report->SetObjectField(TEXT("prepared_full_ring_diagnostics"), PreparedFullRingDiagnostics.ToSharedRef());
|
||||
Report->SetArrayField(TEXT("additional_seed_comparisons"), SeedReports);
|
||||
|
||||
TSharedRef<FJsonObject> Coverage = MakeShared<FJsonObject>();
|
||||
@@ -2342,7 +2465,7 @@ int32 RunRegionEval(const FString& Params)
|
||||
Coverage->SetStringField(TEXT("tunnel_bin_reach"), TEXT("union of finalized warped-SDF and world-chain centerline bounds expanded by their influence radii, plus both conservative bounding spheres"));
|
||||
Coverage->SetStringField(TEXT("warp_coordinates"), TEXT("room bins are queried after the exact live cave warp in the same coordinate domain; tunnel bins union warped-SDF and unwarped world-chain reach"));
|
||||
Coverage->SetStringField(TEXT("tunnel_bin_unit"), TEXT("whole cached tunnel chain; per-chain segment loops remain in the exact evaluator"));
|
||||
Coverage->SetStringField(TEXT("unbinned_writers"), TEXT("passage/landing posts, disturbances, and player diff edits stay in canonical GetDensityAt tail; this is the candidate-bin ablation, not the full region compiler"));
|
||||
Coverage->SetStringField(TEXT("unbinned_writers"), TEXT("passage/landing posts, disturbances, and player diff edits retain their canonical per-sample order inside the chunk block writer pass"));
|
||||
Coverage->SetBoolField(TEXT("route_landing_floor_probes"), PrimaryPassageCount > 0);
|
||||
Coverage->SetBoolField(TEXT("strata_top_and_bottom_boundary_sweep"), true);
|
||||
Coverage->SetBoolField(TEXT("player_carve_and_fill_edits"), true);
|
||||
|
||||
Reference in new issue
Block a user