Skip to content

性能采集实验:已验证经验与对照方法 ​

本页整理2026-09-26至2026-10-26实验中可复用的判断方法(第 9 节为 2026-11-04 补充)。正式指标范围是55/66,其余11项暂停;实验次数、修复次数和构建成功次数不计作新增通过项。下面的E4只适用于各来源明确的设备、系统和受控场景,不是跨设备精度保证。

1. 静止页面为什么可能没有FPS ​

表现:页面静止时FPS与FrameTime留空,CPU或网络仍在更新;动画开始后读数恢复。这与USB断开、目标退后台并不是同一个诊断。

机制:显示器刷新率、画面产生速率、相邻两次实际呈现的间隔是三个量。没有收到新的FrameLifetime,既可能是画面不再更新,也可能是来源延迟。仅凭主机时间推进、连接存活或其它指标更新,不能证明设备端已完整交付一个“零帧”窗口。

已做实验:10月16日用自有测试台固定“静止10秒→30Hz动画15秒→静止10秒→动画15秒→静止10秒”。静止段停用CADisplayLink及周期性UI更新;动画请求只证明刺激发生,不充当实际呈现真值。内部177的五个全新正常UI轮共记录5,290条实际FrameLifetime、658个发布样本,两段动画最小有值率100%,最大恢复观测估计572.952ms。每轮三个预定只读界面取样全部保留,静态中文说明实际可见。

怎么判断:同时看目标前台身份、源到达/设备时钟年龄、真实FrameLifetime、质量标签、动画刺激与恢复。先确认准入通过再Start;不要把失败后才取得的空闲状态倒推为测试前合格。

怎么避免误判:不填FPS=0、不重复上一次FrameTime、不把缺值连成实线;断开或后台用各自原因说明。恢复测试采用固定阶段与预先确定的取样时点,不反复取样直到看到好结果。

证据边界:E4静态说明和受控动画恢复通过;静止零帧窗口的独立完整性仍未证明,恢复毫秒数含时钟桥估计,绝对误差上界未知;本地drop=0不能外推设备端无丢帧。专项原始记录 · FPS当前合同 · FrameTime。

2. 1Hz发布为什么需要更快的新来源 ​

表现:曲线每秒更新,底层却不足1Hz;或者连续数秒都在重复最后一个值。前者会周期性缺点,后者会把断流伪装为连续采集。

机制与实验:系统来源节拍、实时发布节拍、报告聚合节拍各自独立。10月21日Graphics默认约0.99Hz,改startSamplingAtTimeInterval:0.5仍约0.99Hz;在当前环境显式setSamplingRate:5.0后,20秒取得40个事件,实测约1.952Hz。参数5.0不能直接当作5Hz。来源余量实测。CPU、内存、线程和计数率也有各自的来源窗口/唯一消费策略,不能用另一个指标的新消息续命。CPU演进。

判断与避免:逐条核原始窗口/序号、目标生命、sourceEpoch 与到达年龄,再核实际发布。每份合格新来源最多消费一次;无新来源就保留missing /warmup /reset原因。保留Raw不等于必须把同一事实重复发布。验证1Hz连续性时使用事前固定的计划槽,不从好数据反选起点。

证据边界:Graphics频率改变有E3来源资格及后续E4专项;不证明所有系统/所有负载同样频率,也不是独立百分比精度校准。三个GPU专项。

3. 参考工具本身也会影响被测对象 ​

表现:参考记录完整且算法可重算,仍然不能作为合格对照;高频参考可能增加CPU、唤醒或内存开销。

已做实验:10月7日500Hz双API CPU参考在当时设备上的五组完整成本1.25795%–1.34210%,超过预先冻结的1%门,部分组还有漏点,因此该工具路线未准入。它证明参考有扰动问题,不能据此判定产品CPU错误或硬件不支持。成本诊断与停点。

判断与避免:参考先做正常/关闭/取消/恢复资格及OFF/ON成本对照,核完整读写成本、漏点、CPU、内存和尾部。API名称不同不代表内核来源独立,例如公开实现中的getrusage与TASK_EVENTS_INFO可能同源。API调用前后时刻是读取包围,不是设备真实测量时刻;参考包络过宽是不可评估,不能记正常或零误差。

适用边界:引用的百分比只适用于当时工具/场景;后续历史CPU验收沿用与这条失败路线分开。独立校准要同时满足对象、单位、层级、时钟、完整窗口与资源要求。质量与参考范围。

4. 磁盘工作量与网络传输量为什么不是直接真值 ​

表现:应用确实写了或传了文件,但采集器某个统计量为0、缺失或与文件大小不同。

机制:文件逻辑字节、缓存I/O、内核进程磁盘counter、网络协议层字节及整机接口字节不是同一层;进程流量也不同于全设备流量。10月19日磁盘准备曾出现参考全0/非零覆盖不足,后续负载工具调整只作为可证伪方向,未把缓存或调度合并提前定为唯一原因。读取实验与后续结果。

判断与避免:磁盘用完整API读取区间包围产品源窗口,必须有真实非零增量覆盖;网络同时核方向、进程/整机scope、累计起终点、窗口与层级。RVI、对端服务器、应用字节各有诊断价值,但不因总量近似就升为同层同窗精确参考。方向异常只使相应方向失效,仍保管异常Raw;不能把接收坏值抹掉或让它污染独立合法发送值。网络参考用例设计 · 异常传播修复。

证据边界:磁盘有限定E4异常偏离对照;整机网络两项按Owner政策正式通过并保留无独立精度参考标记,不宣称线路字节准确度已校准。网络Canonical。

5. 帧指标要用完整呈现集合、精确阈值和正确分母 ​

表现:同一Session的1Hz FPS均值与逐帧报告AvgFPS不同;阈值恰好相等时误计;删除缺口后每小时次数被放大。

既有合同:实时FPS按时间窗计presentation ;会话平均FPS为N×1e9/Σd_i,其中d为准入原生间隔纳秒。占比按准入间隔计数N;每小时/每十分钟事件率用完整epoch观察跨度T,不能改成只含有效间隔的时长。首点、断点、代际和前后台变化重建基线。

已做实验:10月21–25日逐项测试平均FPS、阈值占比、P95/Jitter、Drop、Jank/Stutter及Smooth,并重新检查完整Metal呈现端点映射。正常阶段局部匹配不代表完整Session同层参考;出现额外、缺失或歧义端点仍不合格。严格阈值以整数/有理数比较,例如Drop差值严格大于8,不是大于等于8;具体公式以各Canonical 为准。平均FPS结果 · Drop边界 · Smooth五轮。

判断与避免:报告旁标出统计对象、时间窗、N/T、quality和算法版本;固定120个源健康槽只证明观察期间来源健康,不是120个独立会话摘要。Smooth是相对中位帧时的RMS分数,可能大于100,不能当0–100“流畅度百分比”。睡眠、CADisplayLink回调或Metal请求数不直接当系统上屏真值。

证据边界:逐项E4正常性与独立Raw算术成立;无完整独立参考的项保留NO_REFERENCE_ACCEPTED_OWNER_POLICY、referenceAccuracyValidated=false,不新增Owner复核门,也不声明永久找不到参考。帧派生Canonical。

6. Energy评分、实际电功率和温度必须分开 ​

表现:Energy有几百的评分、总项不等于分项和、部分字段为负;USB连接时电学量留空。

机制与实验:Energy是源生软件成本评分,不是mW/J/mAh。10月25日Total、CPU和GPU各自五个新轮通过来源唯一消费和异常门,不能借用前项证明后项。GPU场景完成20,281次真实Metal工作,只证明负载存在,不等于有独立功率真值。device测量窗口仍未证,host arrival新鲜度不能替代它。总项 · CPU项 · GPU项。

判断与避免:负值按对应版本字段合同判哨兵,不归零、不用分项相加补Total;Raw原件保留。来源质量修复必须按指标/版本隔离,不能将网络字段的规则泛化给其它Energy项。USB供电下的门禁生效与真正battery-only 数据验证分开;ThermalStatus也不是CPU频率。网络、定位、显示、Overhead及电池热状态当前暂停,不执行后续试验。Energy演进。

7. 冷启动、前台资格和在线发布各有独立边界 ​

表现:自有测试台界面已构建却active=false,刺激没有启动;或Stop后的最终报告完整,但当时实时结果并未完整发布。

实验与机制:静帧专项观察到canvasReady、热状态允许后仍先active=false,约214.6ms后才active=true并准入;它证明UI构建不等于已进入前台,不能事后把组合错误文案唯一归因锁屏或发热。9月末至10月初SW-1在线双sink调查也表明,最终文件存在不能证明事件发出时文件内容已同步,Raw离线重放不能追认当时在线成功。静帧准入证据 · SW-1在线证据增量。

判断与避免:canvas-ready、active、thermal、目标生命、来源武装和结果持久化分别记录;fail-closed使未满足条件时负载/Start为0。用同一nonce/生命、预冻结准入和单次动作,保留升级超时、未执行请求与失败,不重放旧队列。Process Observed Running是主机首次观察,不当设备出生、首帧或业务可用时间。运行观察专项 · Startup演进。

8. 读报告先核统计对象,跨工具比较先核同一性 ​

App CPU可用单核100%的多核累加口径,也可除实际有效核心数表达整机容量份额;核数未知不猜6核。大小核性能不同,时间份额不等于算力比例。跨工具先对齐设备/系统、App版本、操作阶段、启动/静置比例、有效样本及scope,不能用不同日期的两个均值宣称采集误差。

原生报告的1Hz采样均值与Collector原始来源/逐帧Stat可能基数不同;帧会话AvgFPS与1Hz均值本来就不是同一个量。10月26日用户试用反馈又暴露CPU/内存摘要需要更清楚说明统计基数,该对比仍待完成,不能因为wire→events→CSV相等就证明系统数值精度。未选择的Energy/温度为空也不能当0或故障。计算模型 · 原生报告使用与限制 · 月度复盘及待办。

9. 卡顿(Hitch)校准:可控真值与分开录制的参考工具 ​

表现:卡顿候选算法在两个真机 App 上与 Instruments Animation Hitches 对数,一个接近、一个差很多;同时录制时 trace 撑到十几 GB 并卡在停止阶段,无法得到同一次操作的对照。

已做实验(2026-11-03~04,设备 A,iOS 26):

  • Fixture 卡顿校准页按固定时间表运行 100 秒:静止、120 Hz 动画中注入 20/50/100/200 ms 主线程阻塞、重渲染、30 Hz 与 60 Hz 限帧(30 Hz 段再注入 50/100 ms),每次注入写下设备 Mach 时间。它与 Perfowl 帧时间戳同一时钟,可直接对齐。
  • 头两轮全程只有 60 Hz:Fixture 缺少 CADisableMinimumFrameDurationOnPhone = YES,iPhone 上的 App 请求超过 60 Hz 也会被系统限到 60 Hz,与手机设置无关。补上后 120 Hz 段目标间隔为 8.34 ms。
  • 请求 30/60 Hz 时,ProMotion 会把整个屏幕降到 60 Hz,所以 Fixture 单独无法复现“App 限帧低于屏幕刷新率”的情况。这种情况需要屏幕上另有内容维持高刷新率。
  • 同时录制失败后改为分开录制:时间表是确定性的,Perfowl 与 Instruments 各跑一轮,按“段 + 注入时刻”对齐,以 200 ms 那次卡顿定两边的时间偏移。连续动画中的 4 次注入两边逐次一致(时长差不超过 0.1 ms),重渲染段总时长差 3%。
  • Instruments 的口径边界:限帧 App 每帧在上一帧上屏时才开始,这类帧卡住时,Instruments 的帧寿命表有 83/133 ms 的长帧,卡顿表却没有记录;注入卡顿之后紧跟的那一帧晚一个刷新间隔,Instruments 单独计一次。
  • 成本:Animation Hitches 录 140 秒,停止与落盘约 6 分钟;trace 约 1 GB,另在系统临时目录残留约 6 GB 的 ktrace。导出表只有 2 MB 左右。

判断与避免:

  • 自制 Fixture 做帧相关校准前,先核 Info.plist 是否允许超过 60 Hz,并在结果里看实际目标间隔,不要相信请求的帧率。
  • 参考工具很重时不要和 Perfowl 同时录;可以用确定性的 Fixture 分开录,再按事件对齐。注入点给出的是“画面确实停了”的真值,参考工具没有报,不等于 Perfowl 误报,要先确认口径。
  • 录完立即导出需要的表,删除 trace 和系统临时目录里的 ktrace,删除前确认 xctrace 已退出。

适用边界:结论来自一台 120 Hz ProMotion 设备、iOS 26 与 Fixture 场景;卡顿仍是候选指标(candidate v3),未注册 metricID,不进产品界面。真实 App 的对照仍是两次不同的操作,不能当作逐次精度。方案、逐轮数据与 Owner 决定。

10. 在旧系统上做卡顿校准:iOS 15 的四个坑 ​

表现:同一个 Fixture、同一套算法,在设备 A(iOS 26)上 6/6 检出注入卡顿,在设备 B(iOS 15.3.1,60 Hz)上却一次都没检出;注入记录和帧时间也对不上。

已做实验(2026-11-04,设备 B,三轮校准与一次列表滑动):

  1. Fixture 装不上旧系统:最低系统版本原为 16.0,且用了 iOS 16 才有的 ContinuousClock 和 NavigationStack。最低版本改为 15.0,计时换成 DispatchTime.uptimeNanoseconds,导航在 iOS 15 上退回 NavigationView。
  2. 取注入记录:devicectl 不支持 iOS 15。用 pymobiledevice3 的 house_arrest 读取 App 容器:只读 Documents(VendDocuments)要求 App 开启文件共享,否则报 InstallationLookupFailed;开发签名的 App 可以读整个容器(VendContainer)。重签之后 Bundle ID 可能变化,要以会话记录里的为准。
  3. 两个时钟:Fixture 用 mach_absolute_time 记录注入时刻;iOS 15 的 signpost(FrameLifetime 与 Core Animation 提交)用的时钟与它相差约 8,233 s,推测是设备累计休眠时长(未证)。不能直接相减,要用确定的特征对齐:重渲染段 GPU 跑满时屏幕约 15 s 不合成,这是全程最长的无帧间隔,把它的起点对到时间表上,误差约 0.06 s。
  4. 整屏帧看不到 App 卡顿:iOS 15 静止时仍以 20 Hz 合成。App 卡住时,屏幕落回同样的节奏,单看帧无法区分。改看目标 App 自己的 Core Animation 提交间隔,规则见 卡顿时间比 第 4 节。
    • 调参过程中,误报从 428 次降到 9 次,再降到 0 次,靠的是两点:稳态用全部间隔取众数;要求前一个间隔在稳态上、后一个间隔变短。
    • 规则在第一轮数据上调好后不再修改,第二轮校准作为留出数据检验,6/6 检出,误报 0。

判断与避免:

  • 新版本上先确认帧数据到底长什么样,再套算法:抽出注入前后逐帧的间隔、帧寿命、起点间隙和帧种子,看卡顿表现为“帧变长”“节奏降档”还是“完全无帧”。
  • 校准数据只够调一次参数;调完要在新录的数据上原样检验,不要在同一份数据上反复调。
  • 只读探测(直接订阅服务、只统计消息类别)能很快定位“数据根本没到”还是“到了但解析失败”,比反复打包快得多。

适用边界:一台 iOS 15.3.1、60 Hz 设备,Fixture 场景加一段列表滑动;commit 规则是候选,在 Perfowl 产品里的真机复核待完成。滑动段没有注入真值,检出的 2 次卡顿无法判定真伪。逐轮数据与规则演进。

版本历史与来源范围 ​

日期修订证据与限制
2026-10-26首次按八类实验提炼方法,衔接现有唯一指标页及技术演进页本次文档梳理E1;引用历史E2/E3/E4各自限定范围,无新采集,无新增指标验收
2026-11-04新增第 9 节卡顿校准:Fixture 真值、60 Hz 上限、分开录制对照与 Instruments 口径边界Fixture 真机 E4(单设备、iOS 26);算法结论为离线重算 E3,卡顿仍是候选,无新增指标验收
2026-11-04新增第 10 节:iOS 15 上做卡顿校准的四个坑(Fixture 兼容、取注入记录、两个时钟、整屏帧看不到 App 卡顿)与留出验证设备 B 校准 E4 原始数据;规则判定为离线 E3;单设备、单 Fixture 场景

Perfowl · Performance Observer