PERF_FORMAT_GROUP组内可监控的PERF_TYPE_HARDWARE事件数量是否有限制?
PERF_FORMAT_GROUP组中硬件事件数量限制问题解答
问题结论
单个PERF_FORMAT_GROUP组中可监控的PERF_TYPE_HARDWARE事件数量确实存在限制,这个限制来自CPU硬件性能计数器(PMU)的物理数量,而非perf工具或内核的软件限制。
原因分析
现代CPU的PMU提供的通用硬件计数器数量是有限的(比如x86架构常见为4-8个,不同型号CPU差异较大):
- 每个
PERF_TYPE_HARDWARE类型的事件都需要占用一个独立的硬件计数器来同步计数。 - 当组内事件数量超过CPU可用的硬件计数器数量时,perf无法同时调度所有事件进行同步计数,导致整个组的事件数值停止更新。
- 软件事件(
PERF_TYPE_SOFTWARE)由内核通过软件统计实现,不依赖硬件计数器,因此不会受此限制。
你遇到的5个事件正常、6个失效的情况,说明你的CPU恰好最多能同时支持5个你所选的硬件事件。而单独打开事件时,perf会通过时间分片复用硬件计数器(轮流切换事件进行计数),因此能获取到每个事件的数值,但这种方式无法保证事件计数的严格同步。
解决方案
确认CPU硬件计数器能力
- 执行
lscpu查看CPU型号,对应官方文档查询其PMU计数器数量; - 使用
perf stat -e cpu-cycles,cache-references,cache-misses,branch-misses,bus-cycles,stalled-cycles-frontend测试,若命令报错或部分事件无数据,说明这些事件无法同时被硬件支持。
- 执行
优化事件选择
- 合并功能重叠的事件:比如部分细分的停滞周期事件可以用更通用的事件替代;
- 优先保留核心业务关注的事件,移除非必要事件,将组内事件数量控制在CPU硬件计数器支持范围内。
调整监控策略
- 若无法减少事件数量,放弃组模式,改为单独监控每个事件,通过批量读取(如使用
select/poll管理多个fd)减少系统调用开销; - 若需要严格同步的计数,可考虑使用支持多计数器的高端CPU,或利用内核的事件聚合功能(部分内核版本支持)。
- 若无法减少事件数量,放弃组模式,改为单独监控每个事件,通过批量读取(如使用
代码冗余优化
创建子事件时无需设置read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID,仅主事件配置该参数即可,子事件会自动继承组的读取格式。
代码示例修正(可选)
调整子事件的read_format配置:
// 子事件无需设置read_format struct perf_event_attr attr2; attr2.type = PERF_TYPE_HARDWARE; attr2.config = PERF_COUNT_HW_CACHE_REFERENCES; // 移除attr2.read_format的设置 int fd2 = syscall(__NR_perf_event_open, &attr2, 0, -1, main_fd, 0);
内容的提问来源于stack exchange,提问作者Kron
相关产品推荐
相关产品推荐

