From c473feedb3726d23938d0decad1a0f47ca80a2a5 Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 10 May 2026 08:28:45 +0200 Subject: [PATCH] feat(A.5 T23): BUDGET_OVER flag in [WB-DIAG] / [TERRAIN-DIAG] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per Phase A.5 spec §2 acceptance criterion 6: entity dispatcher median ≤ 2.0ms; terrain dispatcher median ≤ 1.0ms at standstill. When the median exceeds the budget, prefix the DIAG line with " BUDGET_OVER" so the regression is grep-friendly during perf testing. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/AcDream.App/Rendering/GameWindow.cs | 6 +++++- src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 2938753..4927cf0 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -8847,8 +8847,12 @@ public sealed class GameWindow : IDisposable long cpuP95HundredthsUs = TerrainDiagPercentile95Micros(_terrainCpuSamples); double cpuMedUs = cpuMedHundredthsUs / 100.0; double cpuP95Us = cpuP95HundredthsUs / 100.0; + // A.5 T23: flag when terrain dispatcher median exceeds 1.0ms budget + // (Phase A.5 spec §2 acceptance criterion 6). Grep-friendly prefix. + const double TerrainBudgetUs = 1000.0; + string terrainBudgetFlag = cpuMedUs > TerrainBudgetUs ? " BUDGET_OVER" : ""; Console.WriteLine( - $"[TERRAIN-DIAG] cpu_us={cpuMedUs:F2}m/{cpuP95Us:F2}p95 " + + $"[TERRAIN-DIAG]{terrainBudgetFlag} cpu_us={cpuMedUs:F2}m/{cpuP95Us:F2}p95 " + $"draws={_terrain?.VisibleSlots ?? 0}/frame " + $"visible={_terrain?.VisibleSlots ?? 0} " + $"loaded={_terrain?.LoadedSlots ?? 0} " + diff --git a/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs b/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs index 5d35f68..3a4db8c 100644 --- a/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs +++ b/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs @@ -583,8 +583,12 @@ public sealed unsafe class WbDrawDispatcher : IDisposable long cpuP95 = Percentile95Micros(_cpuSamples); long gpuMed = MedianMicros(_gpuSamples); long gpuP95 = Percentile95Micros(_gpuSamples); + // A.5 T23: flag when entity dispatcher median exceeds 2.0ms budget + // (Phase A.5 spec §2 acceptance criterion 6). Grep-friendly prefix. + const long BudgetUs = 2000; + string budgetFlag = cpuMed > BudgetUs ? " BUDGET_OVER" : ""; Console.WriteLine( - $"[WB-DIAG] entSeen={_entitiesSeen} entDrawn={_entitiesDrawn} meshMissing={_meshesMissing} drawsIssued={_drawsIssued} instances={_instancesIssued} groups={_groups.Count} " + + $"[WB-DIAG]{budgetFlag} entSeen={_entitiesSeen} entDrawn={_entitiesDrawn} meshMissing={_meshesMissing} drawsIssued={_drawsIssued} instances={_instancesIssued} groups={_groups.Count} " + $"cpu_us={cpuMed}m/{cpuP95}p95 gpu_us={gpuMed}m/{gpuP95}p95"); _entitiesSeen = _entitiesDrawn = _meshesMissing = _drawsIssued = _instancesIssued = 0; _lastLogTick = now;