wip(assembler): round S6 -- in-game cold view counted; workers mostly idle, apply cap not the floor
Direct per-tile trace on the BuildHost actor (owner plan, 2,578 keys): full set 17.4 s legacy; gated coarse-first (after the 9-tile walkable ring) 11.7 s with the ring still at 0.63 s, but full LOD0 slips 2.3 -> 10.2 s. Startup apply boost changed nothing (0.4%). 37.6 worker-s over 17.4 s on 10 slots = ~3.3 busy: the floor is admission/work supply. S5's 251 ms staircase was the trace sampler. Fixed CVar parsing in headless BeginPlay and the 60 m/s crossing instrument. All three knobs stay opt-in. 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
c0596c5f24
commit
b9c13c37c0
11 files changed
+903
-31
No files matched your search
@@ -20,6 +20,7 @@ namespace
|
||||
int32 TileRecordsSeen = 0;
|
||||
int32 TileRecordsWritten = 0;
|
||||
int32 TileRecordsSuppressed = 0;
|
||||
int32 ApplyFrameRecords = 0;
|
||||
TArray<FTileSample> Samples;
|
||||
TMap<FString, double> StageStarts;
|
||||
TMap<FString, double> StageTotals;
|
||||
@@ -94,7 +95,7 @@ namespace
|
||||
|
||||
FString BuildTileGroupJson(const TArray<FTileSample>& Samples, int32 Level)
|
||||
{
|
||||
TArray<double> Request, Queue, Generation, Classify, Mesh, Apply;
|
||||
TArray<double> Request, Queue, WorkerTask, Generation, Classify, Mesh, Apply;
|
||||
int32 Count = 0;
|
||||
int32 Empty = 0;
|
||||
int32 AllAir = 0;
|
||||
@@ -117,6 +118,7 @@ namespace
|
||||
GeometryBytes += Sample.GeometryBytes;
|
||||
Request.Add(Sample.RequestToApplySeconds);
|
||||
Queue.Add(Sample.QueueWaitSeconds);
|
||||
WorkerTask.Add(Sample.WorkerTaskSeconds);
|
||||
Generation.Add(Sample.GenerationSeconds);
|
||||
Classify.Add(Sample.ClassifySeconds);
|
||||
Mesh.Add(Sample.MeshSeconds);
|
||||
@@ -127,6 +129,7 @@ namespace
|
||||
TEXT("{\"count\":%d,\"empty\":%d,\"all_air\":%d,\"all_solid\":%d,\"mixed\":%d,\"vertices\":%lld,\"triangles\":%lld,\"geometry_bytes\":%llu,"
|
||||
"\"request_apply_s\":{\"p50\":%s,\"p95\":%s,\"max\":%s},"
|
||||
"\"queue_s\":{\"p50\":%s,\"p95\":%s,\"max\":%s},"
|
||||
"\"worker_task_s\":{\"p50\":%s,\"p95\":%s,\"max\":%s},"
|
||||
"\"generation_s\":{\"p50\":%s,\"p95\":%s,\"max\":%s},"
|
||||
"\"classify_s\":{\"p50\":%s,\"p95\":%s,\"max\":%s},"
|
||||
"\"mesh_s\":{\"p50\":%s,\"p95\":%s,\"max\":%s},"
|
||||
@@ -136,6 +139,7 @@ namespace
|
||||
static_cast<unsigned long long>(GeometryBytes),
|
||||
*Number(Percentile(Request, 0.50)), *Number(Percentile(Request, 0.95)), *Number(Maximum(Request)),
|
||||
*Number(Percentile(Queue, 0.50)), *Number(Percentile(Queue, 0.95)), *Number(Maximum(Queue)),
|
||||
*Number(Percentile(WorkerTask, 0.50)), *Number(Percentile(WorkerTask, 0.95)), *Number(Maximum(WorkerTask)),
|
||||
*Number(Percentile(Generation, 0.50)), *Number(Percentile(Generation, 0.95)), *Number(Maximum(Generation)),
|
||||
*Number(Percentile(Classify, 0.50)), *Number(Percentile(Classify, 0.95)), *Number(Maximum(Classify)),
|
||||
*Number(Percentile(Mesh, 0.50)), *Number(Percentile(Mesh, 0.95)), *Number(Maximum(Mesh)),
|
||||
@@ -173,11 +177,12 @@ namespace
|
||||
return FString::Printf(
|
||||
TEXT("\"reason\":\"%s\",\"wall_s\":%s,\"tile_records_seen\":%d,"
|
||||
"\"tile_records_written\":%d,\"tile_records_suppressed\":%d,"
|
||||
"\"tile_record_cap\":%d,\"stage_seconds\":%s,\"tile_percentiles\":{%s}"),
|
||||
"\"tile_record_cap\":%d,\"apply_frame_records\":%d,"
|
||||
"\"stage_seconds\":%s,\"tile_percentiles\":{%s}"),
|
||||
*JsonEscape(Reason ? FString(Reason) : FString(TEXT("unknown"))),
|
||||
*Number(FPlatformTime::Seconds() - State.StartSeconds),
|
||||
State.TileRecordsSeen, State.TileRecordsWritten, State.TileRecordsSuppressed,
|
||||
State.TileRecordCap, *Stages, *Groups);
|
||||
State.TileRecordCap, State.ApplyFrameRecords, *Stages, *Groups);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +288,7 @@ void RecordTile(const FTileSample& Sample)
|
||||
TEXT("\"tile\":[%d,%d,%d],\"level\":%d,\"priority\":%d,"
|
||||
"\"request_ordinal\":%llu,\"generation_ordinal\":%llu,\"resident_at_request\":%d,"
|
||||
"\"verdict\":%d,\"proof\":%d,\"empty\":%d,\"vertices\":%d,\"triangles\":%d,\"geometry_bytes\":%llu,"
|
||||
"\"request_to_apply_s\":%s,\"queue_wait_s\":%s,\"worker_queue_s\":%s,\"result_queue_s\":%s,"
|
||||
"\"request_to_apply_s\":%s,\"queue_wait_s\":%s,\"worker_queue_s\":%s,\"result_queue_s\":%s,\"worker_task_s\":%s,"
|
||||
"\"generation_s\":%s,\"classify_s\":%s,\"mesh_s\":%s,\"stream_s\":%s,\"apply_s\":%s"),
|
||||
Sample.TileX, Sample.TileY, Sample.TileZ,
|
||||
Sample.Level, Sample.WorkPriority,
|
||||
@@ -295,10 +300,59 @@ void RecordTile(const FTileSample& Sample)
|
||||
static_cast<unsigned long long>(Sample.GeometryBytes),
|
||||
*Number(Sample.RequestToApplySeconds), *Number(Sample.QueueWaitSeconds),
|
||||
*Number(Sample.WorkerQueueSeconds), *Number(Sample.ResultQueueSeconds),
|
||||
*Number(Sample.WorkerTaskSeconds),
|
||||
*Number(Sample.GenerationSeconds), *Number(Sample.ClassifySeconds),
|
||||
*Number(Sample.MeshSeconds), *Number(Sample.StreamSeconds), *Number(Sample.ApplySeconds)));
|
||||
}
|
||||
|
||||
void RecordApplyFrame(const FApplyFrameSample& Sample)
|
||||
{
|
||||
FScopeLock Lock(>raceLock);
|
||||
if (!GState.IsValid() || !GState->bActive) return;
|
||||
|
||||
FString PendingByLevel = TEXT("[");
|
||||
FString ApplyResultsByLevel = TEXT("[");
|
||||
FString MeshesByLevel = TEXT("[");
|
||||
FString ApplyMillisecondsByLevel = TEXT("[");
|
||||
for (int32 Level = 0; Level < 9; ++Level)
|
||||
{
|
||||
if (Level > 0)
|
||||
{
|
||||
PendingByLevel += TEXT(",");
|
||||
ApplyResultsByLevel += TEXT(",");
|
||||
MeshesByLevel += TEXT(",");
|
||||
ApplyMillisecondsByLevel += TEXT(",");
|
||||
}
|
||||
PendingByLevel += FString::FromInt(Sample.PendingByLevel[Level]);
|
||||
ApplyResultsByLevel += FString::FromInt(Sample.ApplyResultsByLevel[Level]);
|
||||
MeshesByLevel += FString::FromInt(Sample.MeshesAppliedByLevel[Level]);
|
||||
ApplyMillisecondsByLevel += Number(Sample.ApplySecondsByLevel[Level] * 1000.0);
|
||||
}
|
||||
PendingByLevel += TEXT("]");
|
||||
ApplyResultsByLevel += TEXT("]");
|
||||
MeshesByLevel += TEXT("]");
|
||||
ApplyMillisecondsByLevel += TEXT("]");
|
||||
|
||||
++GState->ApplyFrameRecords;
|
||||
WriteEventLocked(*GState, TEXT("apply_frame"), FString::Printf(
|
||||
TEXT("\"frame\":%llu,\"frame_ms\":%s,\"speed_cm_s\":%s,\"apply_ms\":%s,\"drain_ms\":%s,"
|
||||
"\"active_tasks\":%d,\"running_workers\":%d,\"task_cap\":%d,"
|
||||
"\"pending_tiles\":%d,\"pending_results_estimate\":%d,"
|
||||
"\"results_drained\":%d,\"apply_results\":%d,\"meshes_applied\":%d,\"max_applies\":%d,"
|
||||
"\"apply_budget_ms\":%s,\"count_limit_reached\":%d,\"time_limit_reached\":%d,"
|
||||
"\"pending_by_lod\":%s,\"apply_results_by_lod\":%s,"
|
||||
"\"meshes_by_lod\":%s,\"apply_ms_by_lod\":%s"),
|
||||
static_cast<unsigned long long>(Sample.Frame),
|
||||
*Number(Sample.FrameSeconds * 1000.0), *Number(Sample.SpeedCmPerSecond),
|
||||
*Number(Sample.ApplySeconds * 1000.0), *Number(Sample.DrainSeconds * 1000.0), Sample.ActiveTasks,
|
||||
Sample.RunningWorkerTasks, Sample.TaskCap, Sample.PendingTiles,
|
||||
Sample.PendingResultsEstimate, Sample.ResultsDrained, Sample.ApplyResultsByLevelTotal,
|
||||
Sample.MeshesApplied,
|
||||
Sample.MaxApplies, *Number(Sample.ApplyBudgetMilliseconds),
|
||||
Sample.bCountLimitReached ? 1 : 0, Sample.bTimeLimitReached ? 1 : 0,
|
||||
*PendingByLevel, *ApplyResultsByLevel, *MeshesByLevel, *ApplyMillisecondsByLevel));
|
||||
}
|
||||
|
||||
void Finish(const TCHAR* Reason)
|
||||
{
|
||||
FScopeLock Lock(>raceLock);
|
||||
|
||||
Reference in new issue
Block a user