summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/LivingVillage.Desktop/Game.fs22
-rw-r--r--src/LivingVillage.Kernel.Tests/LivingVillage.Kernel.Tests.fsproj1
-rw-r--r--src/LivingVillage.Kernel.Tests/P70PerformanceBaselineTests.fs18
3 files changed, 41 insertions, 0 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs
index 63f69cd..ff1dfe0 100644
--- a/src/LivingVillage.Desktop/Game.fs
+++ b/src/LivingVillage.Desktop/Game.fs
@@ -248,6 +248,14 @@ type LivingVillageGame() as this =
| _ -> 0.0
let perfSoakWatch = System.Diagnostics.Stopwatch()
let mutable perfSoakStarted = false
+ // P70 基准:LV_FRAME_LOG=1 时逐帧打印真实帧间隔(墙钟 ms,含 Update+Draw)与线程分配增量,
+ // 供 scripts/bench-p70.sh + analyze-p70.py 计算平均/最大帧间隔、掉帧与每帧分配。
+ // 仅新增日志,不改变渲染/更新逻辑;配合 LV_PERF_SOAK_SECONDS + LV_AUTOPLAY_SAMPLE 循环 N 秒。
+ let frameLogEnabled = Environment.GetEnvironmentVariable("LV_FRAME_LOG") = "1"
+ let frameLogWatch = System.Diagnostics.Stopwatch()
+ let mutable frameLogIndex = 0L
+ let mutable frameLogAllocStart = 0L
+ let mutable frameLogLastTick = 0L
let mutable prevKb = Unchecked.defaultof<KeyboardState>
let mutable relationView = false
let mutable relationSnapshot: float32[,] option = None
@@ -2240,6 +2248,20 @@ type LivingVillageGame() as this =
(Occupation.saveToken kind) stage world.Tick world.Annals.Length
override this.Update(gameTime: GameTime) =
+ if frameLogEnabled && not splashActive then
+ let allocatedNow = System.GC.GetAllocatedBytesForCurrentThread()
+ if frameLogIndex = 0L then
+ frameLogWatch.Start()
+ frameLogAllocStart <- allocatedNow
+ else
+ let frameMs = frameLogWatch.Elapsed.TotalMilliseconds
+ let allocKb = float (allocatedNow - frameLogAllocStart) / 1024.0
+ printfn
+ "p70-frame index=%d ms=%.3f alloc_kb=%.1f tick=%d panel=%s"
+ frameLogIndex frameMs allocKb world.Tick (M5Interaction.panelName m5View)
+ frameLogWatch.Restart()
+ frameLogAllocStart <- allocatedNow
+ frameLogIndex <- frameLogIndex + 1L
let kb = Keyboard.GetState()
let pressed (key: Keys) = kb.IsKeyDown(key) && not (prevKb.IsKeyDown(key))
let pressedAny (keys: Keys list) = keys |> List.exists pressed
diff --git a/src/LivingVillage.Kernel.Tests/LivingVillage.Kernel.Tests.fsproj b/src/LivingVillage.Kernel.Tests/LivingVillage.Kernel.Tests.fsproj
index 1a36ea7..ade9f44 100644
--- a/src/LivingVillage.Kernel.Tests/LivingVillage.Kernel.Tests.fsproj
+++ b/src/LivingVillage.Kernel.Tests/LivingVillage.Kernel.Tests.fsproj
@@ -17,6 +17,7 @@
<Compile Include="OccupationBiasTests.fs" />
<Compile Include="OccupationStoryTests.fs" />
<Compile Include="PerformanceTests.fs" />
+ <Compile Include="P70PerformanceBaselineTests.fs" />
</ItemGroup>
<ItemGroup>
diff --git a/src/LivingVillage.Kernel.Tests/P70PerformanceBaselineTests.fs b/src/LivingVillage.Kernel.Tests/P70PerformanceBaselineTests.fs
new file mode 100644
index 0000000..ea98f34
--- /dev/null
+++ b/src/LivingVillage.Kernel.Tests/P70PerformanceBaselineTests.fs
@@ -0,0 +1,18 @@
+namespace LivingVillage.Kernel.Tests
+
+open Microsoft.VisualStudio.TestTools.UnitTesting
+open LivingVillage.Headless
+
+/// P70:把 Headless `--performance-baseline`(defaultConfiguration)的最终 digest 钉住,
+/// 作为 Kernel/Sim 数值路径漂移的护栏。与 scripts/bench-p70.sh 的 Kernel 档同一输入。
+[<TestClass>]
+type P70PerformanceBaselineTests () =
+
+ [<TestMethod>]
+ member _.PerformanceBaselineDigestIsPinned () =
+ let world = PerformanceProbe.runSteps PerformanceProbe.defaultConfiguration
+ let digest = PerformanceProbe.worldDigest world
+ printfn "P70 performance baseline digest=%s" digest
+ Assert.AreEqual<string>(
+ "953775FAEB2FDDE97289491AA260BD8D390C571E48A7A13AD2CB6FB7124F7F6C",
+ digest)