Skip to content

指标计算模型与窗口语义 ​

Perfowl 的指标不是“收到一个字段就画一条线”。一个正式数值至少同时依赖:

text
Source Fact
+ Identity / Scope
+ Clock Domain
+ Window / Baseline
+ Freshness
+ Quality Gate
+ definitionVersion

这页建立所有指标共享的计算理论。具体 metricID 的字段、单位和版本仍以 Registry 指标合同索引 与各 Canonical 指标页为准。

一、十类计算模型 ​

计算模型代表指标核心算法首点 / 窗口行为
Gauge APP CPU、Memory、GPU Utilization、Energy当前有效原值或明确单位换算首个有效样本可发布;source 不可用时 missing
Cumulative Counter RateCSwitch、Wakeups、Disk(current - previous) / elapsed首点只建 baseline;counter reset 后重新 warmup
Interval Rate Device / Process Networkinterval amount / interval duration必须有完整有效窗口;不同 clock domain 不混算
Event IntervalFrameTime当前事件与明确前驱事件的设备时钟间隔第一事件只建 anchor;断链后重新 warmup
Rolling Count新 Display FPS 目标模型trailing window 内事件数量窗口随时间推进;source 健康但窗口无事件时可为真实 0
Rolling PercentileP95 FrameTime最近固定窗口 valid event 的 nearest-rank percentile样本不足时 warmup / missing,不用 0 填充
Rolling DistributionRefresh Rate 分布对有效 source-native interval / rate 做时间窗口或 Session bucketdisplay/source 切换时必须断开
Rolling Derived MetricFrame Pacing JitterP95(FrameTime) - P50(FrameTime)依赖同一窗口中的两个有效统计量
Session AggregateP50/P90/P99/Max、1% Low、Jank/Stutter对整段有效事件序列聚合只消费符合 quality/scope 的样本
Conditional / Source-nativeBattery Power、Energy、GPU Counter物理条件公式或 Apple source-native value条件不成立时 missing/not-applicable;未知字段不猜单位

二、Source Cadence、Publisher Cadence、Report Cadence 是三件事 ​

很多误解来自把“底层事件有多快”与“工作台多久刷新一次”混在一起。

text
Source Cadence
设备事件/采样原始到达节拍
        ↓
Domain / Metric Processing
逐事件或逐窗口计算
        ↓
Publisher Cadence
产品 MetricFrame / UI snapshot 发布节拍
        ↓
Report Cadence
在线统计、Session 聚合与最终报告节拍

例如 FrameLifetime 可以几十次/秒到达,而产品工作台仍按约 1 秒发布一次 Display Performance snapshot。降低 UI 发布频率不能替代底层 source 降带宽;反过来,底层高频事件也不要求 UI 每条事件都重绘。

三、Freshness:什么时候可以沿用上一个值 ​

不同指标的“新鲜度”规则不同。

Freshness 类型例子没有新原始数据时的正确行为
Gauge freshnessCPU、Memory可以在当前有效采样点发布最新 gauge;source 超时后必须 missing
Event freshnessFrameTime只有出现新的有效 event interval 才发布;不能重复上一帧 FrameTime
Window freshnessFPS、P95、Jitter依据当前滚动窗口重新计算;旧事件随窗口淘汰
State freshnessforeground、Startup lifecycle状态变化本身会重置依赖前值的算法
Conditional freshnessBattery Power物理前置条件一旦失效立即置空,不保持上一次放电值

因此:

text
CPU 没有在每个 UI tick 变化
≠ 必须立刻清空

FrameTime 没有新帧
→ 不得重复上一帧值

Display FPS source 健康 + 前台 + 最近 1 秒没有新 presentation
→ 可以是真实 0

source 不可用
→ FPS 必须是 missing,而不是 0

四、Warmup 与 Baseline ​

依赖前值的算法都必须先建立 baseline:

text
Counter Rate
Network Delta
FrameTime
Rolling Window

首个样本通常只能证明“source 已经开始返回事实”,不能凭一个点构造时间差。

例如:

text
counter sample #1
→ 保存 previous counter
→ quality = warmup

counter sample #2
→ current - previous
→ elapsed > 0
→ rate

FrameTime 同理:source/reconnect/foreground/display 边界后的第一帧只重新建立 anchor。

五、统一断链合同 ​

只要一个算法依赖“上一条”或“最近窗口”,下面任一边界发生时都必须评估是否清空状态:

  • sourceEpoch 改变;
  • reconnectGeneration 改变;
  • targetGeneration / PID identity 改变;
  • target foreground → background → foreground;
  • displayID 改变;
  • cumulative counter 下降或 reset;
  • clock domain / source timestamp 类型发生变化;
  • schema 或 source role 发生变化。

默认原则:宁可重新 warmup,也不要跨不连续边界制造一个数学上可算、物理上不存在的值。

常见例子 ​

text
PID 1564 counter
+ App 重启后的 PID 1832 counter
≠ 一个连续 rate
text
Display 1 FrameLifetime
+ Display 2 FrameLifetime
≠ 一个连续 FrameTime sequence
text
foreground 最后一帧
+ background SpringBoard 若干帧
+ foreground 第一帧
≠ 目标 App 一段连续帧时间

六、0、missing、warmup、not-applicable 不可互换 ​

状态真实含义能否参与统计
0经过有效窗口和身份门禁后,系统事实确实为零可以
missing没有足够事实得到这个值不可以
warmupsource 已工作,但算法 baseline / window 尚未成立不可以
not-applicable当前 App 架构或物理条件不存在该语义不可以
not-foregroundforeground-device 指标当前不属于目标 App不可以
counter-reset / discontinuity前后样本不能安全连续计算不可以

完整质量字典见 数据质量与 0 值判定准则。

七、三个典型算法示例 ​

1. Network Rate ​

text
currentBytes - previousBytes
----------------------------
elapsedSeconds

要求:同 source、同 identity、同 clock domain、elapsed > 0。counter 下降或进程 generation 变化后重新 warmup。

2. FrameTime ​

当前目标架构使用明确 presentation 前驱关系:

text
FrameTime = currentPresentation - previousPresentation

真实实现必须使用设备 source timestamp / Mach timebase,不允许用 hostReceiveMonotonicNs 冒充帧发生时刻。Display Performance 切源完成前,当前 production source 以 Registry 合同为准。

3. Rolling FPS ​

目标 Display Performance 模型:

text
FPS(t) = count(valid presentation timestamps in (t-1s, t])

它是一个窗口吞吐指标,不是 1000 / 当前 FrameTime。窗口可以借助 host monotonic 推进“现在”,但 host 时间只能用于窗口淘汰,不能生成不存在的 presentation timestamp 或 FrameTime。

八、时钟规则 ​

任何差值计算都要先确认两个端点属于同一个 clock domain:

text
Device Mach ticks
↔ dynamic numer / denom conversion

Host monotonic
↔ host elapsed / receive / publisher window

Source-native Cocoa timestamp
↔ 仅与同源相邻 timestamp 相减

禁止:

text
Device event timestamp - host receive timestamp

old source clock - new source clock

不同 display / generation 的 timestamp 直接相减

具体时钟、bridge 与 Session timeline 见 数据流、时钟与断链规则。

九、公式版本为什么必须冻结 ​

以下任何变化都应该视为指标定义变化,而不只是“实现优化”:

  • source ownership 改变并导致语义改变;
  • scope 改变;
  • unit 改变;
  • rolling window 长度改变;
  • percentile 算法改变;
  • freshness 规则改变;
  • reset / discontinuity 规则改变;
  • 取整、bucket 或合法 0 语义改变。

发生定义变化时,Canonical 页、Registry definitionVersion、报告和 replay 必须保持可审计一致。历史 Session 应按原始版本回放,不用新公式静默改写历史结果。

十、阅读顺序 ​

text
本页:计算模型
    ↓
数据流、时钟与断链规则
    ↓
数据质量与 missing/0
    ↓
具体 Canonical 指标页
    ↓
Registry 指标合同索引

2026-10-26 · 采样均值、来源Stat与会话派生量 ​

原生结果窗的采样均值是选定区间内、同scope/unit/代际且符合numeric质量合同的有限值Σv/n;Collector Stat可能来自更密的来源序列或逐帧集合。即使同一Session,两者也须先核输入窗口、有效点基数、质量过滤和算法版本,不能直接当同一统计量。采样均值不是默认时间加权均值,可用点比例也不是连续时间覆盖率。

单核100%口径的进程CPU允许多核累加超过100%;除以同窗有效核心数才是相应整机容量份额,核心数未知不猜测,大小核时间份额不是性能等价。单位相同仍需核scope。跨工具还须同设备/系统/版本/场景和操作窗口,不用不同日期均值给精度结论。

会话AvgFPS为N×1e9/Σd_i;1Hz FPS算术均值与它并不相等。滚动P95均值不等于全程P95,事件率T不能只计有效间隔。10月26日用户试用暴露CPU/内存概览与Collector Stat统计基数需进一步逐源核对,目前未完成全面对比,不据此宣布算法错误或准确度校准。原生报告合同 · 帧派生Canonical。

版本历史增量:2026-10-26,补统计对象与跨工具比较方法,E1复盘,不改计算公式或实现。月度复盘与来源索引 · 实验判断方法

Perfowl · Performance Observer