Skip to content

Context Switch Rate(上下文切换速率) ​

最新上下文切换率 · 2026-10-18(1Hz candidate限定E4):五新生命/Session固定120真实due机会/120槽,独立self-task计数异常、一次发表与连续性门通过;非due保留null/not-due,不重复旧值。留存18/66(启动12/12、新非启动6/54),内部b187已覆盖,下一仅中断唤醒率。记录。

当前共享采集源(2026-10-07 G84):产品 SysmontapRawAdapter._make_stream 先用同一个 pymobiledevice3 原生 DeviceInfo 查询时钟与支持列,再用原生 Sysmontap 构造器建立完整14消费者固定依赖闭包(11进程列、3系统列);默认 intervalMs=500、ur=500 ms、sampleInterval=500000000 ns,保留CPU元数据与原生时钟。必需列缺失、非法类型或重复时明确失败,不以减少指标、补值或旧值续点降级。此为采集配置修复,不改变本页数值公式、scope、单位、质量/候选标签与独立误差门;完整54项与正式五轮仍待验,源码/安装验证不等于本指标数值校准。方案与验证。

作用域属性:[进程级 · 目标专属](Process Scope )

1. 定义与业务价值 ​

上下文切换速率基于目标进程 ctxSwitch 累计计数的增量计算,表示目标进程线程发生调度上下文切换的频率。切换的另一端可能是同进程线程、其他进程线程或系统工作,因此不能把它限定解释为“目标进程内部线程互切”。持续升高可作为锁竞争、过度并发或调度压力的候选信号之一。

2. metricID / scope / unit / source ​

字段值
metricIDios.process.scheduler.context_switch_rate
scopeprocess
unitcount-per-second
sourcedvt.sysmontap
sourceKeyctxSwitch
definitionVersion counter-rate.source-clock.exact-counter.candidate.v3

取自当前 Registry 。

3. iOS 系统原理 ​

上下文切换发生在调度器改变 CPU 当前执行上下文时,会产生调度开销。sysmontap 暴露的 ctxSwitch 是目标进程相关的累计计数器,Perfowl 对相邻样本做差分得到速率;当前文档不进一步假设每一次切换的另一端属于哪个进程。

4. 系统服务 / 通信通道 / 采集命令与实现 ​

通道:com.apple.instruments.server.services.sysmontap(DTX )。采集:pymobiledevice3 原生 Sysmontap(provider, process_attributes, system_attributes, interval_ms=intervalMs) 返回累加字段 ctxSwitch;速率推导是 Perfowl 自研逻辑,实现于 MacApp/Sidecar/perfowl_collector_core/metric_engine.py::RawMetricEngine._counter_rate。

5. 原始字段与字段语义 ​

Processes[*].ctxSwitch:sysmontap 回包中的进程级累计上下文切换计数。Perfowl 在 source epoch / reconnect 变化时重建自己的差分基线,不等于底层累计计数器本身被系统清零。

6. 精确公式 ​

text
identity = (target_pid, target_generation, source_epoch, reconnect_generation, adapter_id, "ctxSwitch")
rate = (current_ctxSwitch - previous_ctxSwitch) / elapsed_seconds
clock_ns = floor(EndMachAbsTime * numer / denom)
elapsed_seconds = (clock_ns_now - clock_ns_prev) / 1e9

来源:metric_engine.py::_counter_rate(第 421~443 行)。身份键包含 source_epoch 与 reconnect_generation,因此设备重连或采集源重启会开启全新的计数窗口,不会跨重连计算速率。

2026-10-03 R5算式补充:clock_ns=floor(EndMachAbsTime*numer/denom),rate=counter差分/设备clock_ns差分秒数。SysmontapRawAdapter在同一DVT provider准备时仅查询一次 DeviceInfo.mach_time_info() / machTimeInfo,保存原始返回值 [absoluteTicks,numer,denom,...] 于Raw的sysmontapMachTimeInfo(numer/denom取索引1/2,非硬编码);查询超时≤3 s。显式坏钟/缺钟为null/missing -clock,历史完全缺新增字段才走candidate-host-window。clock模式/比例纳入差分身份键,切换warmup ;负哨兵source-sentinel;计数下降counter-reset;重复/倒退时钟invalid-window且不污染前进基线。合法0要求计数相同且有效正时差。不从来源差分推断物理硬件带宽。R5修复记录。

7. Clock / Window / Freshness ​

Clock domain:设备EndMachAbsTime,由同一DVT provider的machTimeInfo实测numer/denom转换。窗口:相邻设备端点;历史缺该字段仅允许带candidate-host-window标签的host fallback。

8. Baseline / Reset / Discontinuity ​

  • 首次观测(无前值)→ warmup,值为 None;
  • 若当前计数值小于前值(如目标进程崩溃重启)→ counter-reset,值为 None,不产生负值或虚假尖峰;
  • 若 elapsed_seconds <= 0 → invalid-window。

9. Quality:valid / candidate / missing ​

current 字段缺失或 target_pid 为空 → missing;否则按上节规则返回 warmup / counter-reset / invalid-window / candidate 之一。

10. 合法 0 的条件 ​

速率可以合法为 0(该窗口内确实没有发生上下文切换,理论上极少见但不排除);需与 missing/warmup/counter-reset 状态区分,不得把这些状态误显示为 0。

11. 当前证据、校准与平台覆盖 ​

2026-10-18按Owner确认1Hz完成五新生命专项:来源/连续性/self-task包络异常与真实Swift限定E4通过,非物理精度或私有producer等价;见本页最新记录。旧联合会话不计本次分母。

12. 如何分析:能得到什么结论,不能得到什么结论 ​

能得到:目标进程线程切换的频率变化趋势,可用于同版本回归对比。

不能得到:不能仅凭切换速率飙升直接断定"锁竞争"——需要结合线程状态、Instruments 或代码级证据;不能与其他 App 或系统整体的切换频率做跨作用域比较(本指标是 process scope)。

13. 常见误区 ​

  • 把切换速率突增直接等同于"死锁"或"过度加锁"的确诊,而不做交叉验证;
  • 把 counter-reset 状态误当作"业务真实速率为 0"。

14. Legacy / 历史实现 ​

counter-rate.source-clock.exact-counter.candidate.v3 是当前版本;counter-rate.source-clock.candidate.v2 仅为历史版本;旧 counter-rate.v1 使用宿主到达时差,旧Session不回写。

15. 版本历史与来源批次 ​

本页由 site/knowledge/metrics/system-condition-metrics.md 拆分而来。

版本日期修订要点
v1(本页)2026-09-18从 system-condition-metrics.md 拆出,成为独立 Canonical;补充 _counter_rate 精确身份键与状态机。

| counter-rate.source-clock.candidate.v2 | 2026-10-03 | R5:设备源钟消除宿主队列压缩对速率分母的放大;旧host fallback显式标记,当前真机与校准边界参见R5。 |

2026-10-05 G11 精确累计数与质量边界 ​

当前算法 counter-rate.source-clock.exact-counter.candidate.v3:原生UInt64累计值保存为精确整数,先相减,再把安全delta除以真实来源窗口秒数;不先转Double累计值。2^53以上累计值仍可有精确的小增量;计数下降先判counter-reset/置空。delta大于2^53−1时precision-loss/置空并以当前有效累计值更新下一基线。浮点来源仅有限非负、整数形态且≤2^53−1接受并转为等值int,非整数float为invalid-counter;较大浮点的低位未被取证,不恢复成整数;超UInt64整数precision-loss,负哨兵source-sentinel,bool/非数字/NaN/Inf缺值。真0仅在有效正窗口且真实累计值未变时成立。

Checkpoint保留JSON整数,不把大整数转Double;对不精确浮点/负/超界基线拒绝恢复,旧formulaContract不匹配则重建,不回写旧Session或补造缺窗。作用域、单位、设备Mach/历史host候选时钟及身份/重连规则未变。这是算术可信边界修复;独立E4误差与五轮100%仍待验证,未证为此前断续的根因。

版本日期变更与证据
exact-counter.candidate.v32026-10-05精确整数差分/重置与checkpoint,来源 G10/G11合同及结果,E2匹配验证;不升级独立校准支持

采集源版本更新 · 2026-10-07 ​

G84将SDK全列factory改为固定共享11+3列、输出与采样节拍一致;原生服务/DTX通道不变,支持列仍由SDK查询,传输及指标转换为Perfowl适配层,SDK来源和自研计算分开。初missing、counter warmup/reset、VM近似质量等原边界保留,不外推其他设备/场景持续100%。来源批次。

2026-10-18 · 新来源一次发表与独立参考准备(E2,尚未专项验收) ​

现象与复现:两个原生累计端点已得到一个速率后,若直接读取“最近派生值”,停止新来源十秒仍可重复同一数字;曲线看似不断点,却不是新的观测。精确主线和当前安装版本均用纯软件双端点夹具复现,不据此推断真机数值误差。

本项候选修复:新增process-context-switch-source-once.v1发表政策,数值公式仍为v3;每个值绑定两份原始累计、两个原生EndMachAbsTime及来源序列,独立固定容量6的一次消费队列。host收到后的有效期是来源间隔三倍,默认1.5秒;设备差分窗口超过该长度重新warmup。无新源、绑定错或坏钟缺值,不以缓存标量续点。相同设备端点/累计的良性重复不新增观测,也不应丢掉尚未发表的合法窗口;冲突重复清pending。源或比例变化先warmup后恢复,持续拒绝倒退代际。历史未标记Session保持历史行为,不补造可信度。

独立对照的边界:自有测试App拟在显式开启时记录自身TASK_EVENTS_INFO.csw与实际调用前后Mach时刻,默认配方不新增调用。它与Sysmontap是不同读取路径,但不是物理仪器,也不是Apple私有producer等价证明。公开XNU会将该signed32字段饱和到INT32_MAX,达到饱和值须拒绝差分,不解释为正常0或UInt32回绕。公开getrusage总切换计数内部也来自该task接口,不能充当第二个独立参考。

判读与避免:先证明原始累计/设备时钟/身份一致,再证明一个源窗只发表一次;以预先固定的参考时间括点和宽度判断普通异常,不按产品值挑参考点、不把无法对照的窗口填正常。工作线程数、唤醒配置和锁次数均不等于真实切换数。新参考先通过默认OFF兼容、原生API资格与CPU/内存/完整记录时延预算后,才开展五个新生命专项;当前尚未开展,不增加验收计数。来源方案与增量验证。

版本日期变更与证据
source-once 候选2026-10-18E2缓存续点复现、精确双counter/一次发表控制;独立参考准备,真机专项与物理准确性未通过

2026-10-18 · 来源频率与显示频率须分别验收(E4诊断,专项未通过) ​

表现:来源一次消费修复后,旧数字不再重复续点,但固定0.5秒显示机会仍偶有缺值。不能因此恢复旧缓存来“修复连续性”,也不能只看曲线连线判断数据有效。

已验证事实:本场景140秒真实产品诊断,固定窗233/240个机会有新计数窗口,113/120个秒槽完整;233点独立self-task计数包络对照均为普通范围、严重偏离0、来源违规和拒绝0,最大空档1秒,原覆盖门仍未通过。primary进程窗口实际平均514.840ms,虽配置请求250ms,仍未达到稳定每秒两个新进程计数。另一个完整11字段125ms原生控制平均517.566ms;单独新DTX、仅身份/ctxSwitch/procAge且关闭CPU与footprint计算的125ms控制平均519.677ms。后两例是同一闲置自有App的短12秒控制,合法计数增量0,不代表业务负载精度或所有设备/配置的硬限。

判断方法与边界:从连续原始EndMachAbsTime和timebase计算实际进程源间隔,分别统计System-only、primary与supplemental,不能用系统回包频率冒充进程计数频率;对所有预定显示机会保留缺点与分母。若真实源慢于发表要求,固定容量缓冲只能吸收抖动,不能无限产生新观测。更快配置请求不保证更快数据;短控制仍未证明其他系统路径技术上绝不可能达到2Hz。

避免方式:优先给此类计数指标登记可实现的刷新频率,并由Owner确认交付范围;不复制旧速率、不插值伪装新源、不缩原失败分母、不把明确的合法0与缺源混同。目前已提出仅此指标以每秒1个真实新值验收,等待范围确认,尚未改变正式门、未启动新五轮或增加验收计数。

工具教训:当JSON导出数组与JSONL原件同时核对时,一次解析导出、逐行读取原件并在核对后释放,避免同时常驻两份大型对象;直接RSS预算与产品数值门是两个独立条件。CSV六位小数要按明确舍入精度核对,原始JSONL仍按原始数值核同;Python tuple/datetime与JSON list/string须先归一化表示,不能把表示差异误报成证据漂移。该方法不解除真实采集失败或资源停止。详情见本批诊断及停止记录。

版本日期变更与证据
来源频率诊断2026-10-18固定233/240覆盖失败、独立计数/消费者核对与原生短控制;专项仍未通过,1Hz交付范围待Owner确认

容量判断补充(同日,E2离线复核E4原件):对固定窗口内的机会,先数“首机会之前TTL范围内到末机会时已收到”的不同合法源窗,得到保守容量上界;即使允许无限缓冲且不扣除窗前已消费源,上界仍低于要求时,仅改队列策略就不能达标。本次上界235而原门238、实际233,必须区分来源能力/交付频率与计算错误。这个方法只针对已记录来源和现行一次发表/TTL契约,不证明另一个来源或设备永远达不到;不据此回改原失败分母。

2026-10-18 · Owner确认1Hz交付范围(实现/专项待验收) ​

仅本指标采用每秒一个真实新值;CPU等仍原节拍,不重判旧233/240失败。来源间隔、host TTL与显示间隔分别登记:显示1秒不把1.5秒TTL或原生窗口上限翻倍。due基于原ready时刻+0.25s+k秒;中间500ms非due行保留null/not-due,不复制旧值;due无新源仍missing。每个due取最近未用的合法原始窗口,跳过中间窗口是明确降采样而非Raw丢失,不把相邻源窗混算成1秒平均。图形只略过明确非due空行,真实缺due仍断线;导出保留null与质量,不以视觉连接新增有效数据。新未来验收固定120个due机会/120槽,来源/完整≥119、普通≥114,gap仍≤1.5秒及全部原数值/尾部门,五新生命要求保持。实现、软件资格及真机结果以本批增量合同为准,当前未增加验收数。

专项验收更新 · 2026-10-18 ​

固定原ready+[15,135)秒:120个due=origin+15.25s+i秒、120秒槽,源/完整≥119、普通≥114、gap仍≤1.5秒,严重含全尾段0、来源拒绝违规0、连续偏离≤2。非due半秒行完整保留但不算有效点或丢失;漏due不许转为not-due或删分母。每轮前600秒,五轮冷却合计3000.078秒,140秒低中阶梯和100Hz自有计数不变,首失败停、不补轮。持续4×75%高负载及其他设备/App泛化未验。

发表政策process-context-switch-source-once.1hz.v2与数值公式v3分离。全局wire/CPU仍500ms;本项按计划时刻而非处理/次数选due,取最近未消费的相邻原始counter窗,不拼接平均、缓存复用或插值。两累计整数先减、原生Mach timebase精确换算、1.5秒来源TTL与窗口上限保持;坏/缺源/错绑定/重置缺值,合法等累计0可发表一次。无marker及v1历史回放保持,不追认新验收。明确not-due行在图形只被略过,不生成数值;真实due缺值或gap>1.5秒仍断线,导出保留null与质量。

参考是自有App显式开启的task_info(TASK_EVENTS_INFO).csw100Hz原始有符号计数、调用前后ticks与状态;饱和/负值/缺侧不可比。固定时间括点(端点/内部gap≤30ms),包络宽≤max(20/s,15%),普通外扩max(20/s,15%)、严重max(40/s,30%);不按产品值挑参考、不将配置线程/唤醒数冒充切换数。公开XNU和getrusage内部相同计数路径不提供第二独立校准,未证本机内核等价。

软件135文件2396方法、原35来源+新19时序控制、12独立1Hz evaluator和17独立算术/监督控制通过;实际候选归档534适用方法,4源文本门另在完整源码过、1旧receiver矛盾既有排除,原失败不抹除。2065其他压缩模块/12外条目保持;原归档kwdefault漏嫁接在未安装R2被控制抓出,R3已修class默认值并保留其他方法。真实37Core16输入与实际GUI44Core16输入/全部1461正式sample的模型/Codable/CSV/JSONL/质量核同。GUI51源63.669秒构建,源SHA不变,保留共享WIP而非干净main全GUI重建。

同489进程约49KB、10000完整处理mean/P95旧0.315066/0.442620ms→新0.319921/0.447287ms,原≤1ms门成立,不承诺每次≤1ms;新首点/最大2.356416ms,30000突发容量6/29993旧pending丢弃而Raw不丢。正式参考完整记录平均0.134843–0.148863ms、P95 0.243625–0.246417ms、最大83.023292ms;五轮各230s/192MiB内,最终分离审核20.981s/RSS121540608B。

历史2Hz与容量前置工具资源失败均原样保留;新1Hz五正式不借旧样本。内部b187/公证暂缓/GPL/非干净main全GUI构建分列。下一中断唤醒率不顺带通过。

版本日期修订与来源
source-once.1hz.v22026-10-18每秒一个真实新值、not-due与missing分开;五新轮限定E4异常对照与连续性。记录 · 快照

Perfowl · Performance Observer