You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读取__NR_perf_event_open返回fd中的CPU周期与指令数?

关于perf事件组的读取逻辑解析

1. perf_event_open事件组的读取规则

当你通过perf_event_open创建事件组(多个事件绑定为一组,由一个组leader管理)时,读取文件描述符的返回格式是固定的:

  • 每个事件的读取结果会成对出现:第一个是该事件的时间戳/序号(64位无符号整数),第二个才是事件的实际计数
  • 最后还会额外返回一个全局的同步时间戳,用来保证组内所有事件的计数是同一时间段采集的

所以对于N个配置的事件组,读取到的uint64_t数组长度就是2*N + 1——每个事件占2个元素,加最后1个同步值。

2. 奇数索引位存实际结果的原因

以你提到的2个事件(CPU周期、指令数)为例:

  • 索引0:第一个事件(CPU周期)的时间戳
  • 索引1:CPU周期的实际计数
  • 索引2:第二个事件(指令数)的时间戳
  • 索引3:指令数的实际计数
  • 索引4:全局同步时间戳

这是perf子系统的设计:事件组的读取返回每个事件的"元数据+计数"对,目的是让你能验证组内事件的同步性——比如两个事件的时间戳是否一致,以此确认计数是同一时间段的有效数据。

3. 单配置与多配置读取的差异

  • 单配置(非组):直接读取单个uint64_t值即可,因为没有同步需求,perf子系统只返回事件计数,不需要额外的时间戳和同步值
  • 多配置(事件组):必须按成对的格式读取,因为组的核心价值是保证所有事件的计数原子性同步采集,额外的时间戳就是用来验证这一点的——如果组内事件的时间戳不一致,说明采集过程中发生了中断或上下文切换,计数可能不准确,你可以选择丢弃这次结果

4. 对应Lemire代码的end()方法逻辑

Lemire的代码里直接取奇数索引的数值,是默认信任perf子系统的同步机制,跳过了时间戳的校验步骤,直接提取有效计数。如果需要更高的严谨性,你可以先检查所有事件的时间戳是否与最后一个全局同步值一致,再使用计数。


内容的提问来源于stack exchange,提问作者chenzhongpu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:22:09