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

perf_event_open无法监控HW_CACHE写入与预取事件求助

解决PERF_TYPE_HW_CACHE写入/预取事件无法注册的问题

问题核心

你遇到的情况是:PERF_TYPE_HW_CACHE类型下,读相关缓存事件可正常注册并统计,但写入、预取类事件无法通过perf_event_open创建,本质原因通常分为三类:CPU硬件不支持目标事件、事件编码或属性配置错误、内核权限/版本限制。

分步排查与修复

1. 先加错误校验,明确失败原因

你的代码未对perf_event_open的返回值做检查,这是排查的第一步。添加错误输出,直接定位问题:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/syscall.h>
#include <linux/perf_event.h>
#include <unistd.h>
#include <stdint.h>

struct read_format {
  uint64_t nr;          
  struct {
    uint64_t value;     
    uint64_t id;        
  } values[];
};

int main() {
  struct perf_event_attr attr1;
  memset(&attr1, 0, sizeof(attr1)); // 必须初始化结构体
  attr1.size = sizeof(struct perf_event_attr); // 内核会校验该字段,缺失直接失败
  attr1.type = PERF_TYPE_HW_CACHE;
  attr1.config = ((PERF_COUNT_HW_CACHE_L1D) | 
                  (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | 
                  (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16));
  attr1.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
  
  int main_fd = syscall(__NR_perf_event_open, &attr1, 0, -1, -1, 0);
  if (main_fd == -1) {
    fprintf(stderr, "perf_event_open failed: %s\n", strerror(errno));
    return 1;
  }
  
  // 后续逻辑...
  close(main_fd);
  return 0;
}

如果错误是Invalid argument(EINVAL),基本可以确定是CPU不支持该事件,或者编码错误。

2. 验证系统支持的缓存事件

用perf list命令查看当前CPU实际支持的缓存事件:

perf list cache

输出会列出所有可用的缓存事件,比如Intel CPU可能显示:

L1-dcache-loads                                   [Hardware cache event]
L1-dcache-load-misses                             [Hardware cache event]
L1-dcache-stores                                  [Hardware cache event]
L1-dcache-store-misses                            [Hardware cache event]

如果找不到对应写入/预取的事件,说明你的CPU硬件不支持直接统计该类型事件,需要改用raw硬件事件编码。

3. 针对CPU架构调整事件配置

不同CPU架构的缓存事件支持差异极大:

  • Intel CPU:写入类事件通常对应L1-dcache-stores,预取事件大多没有单独统计项,需改用cpu/mem-loads,ldlat=30/P这类raw事件(具体编码需查对应CPU的手册)。
  • AMD CPU:部分型号的L1写入事件编码可能需要调整,或需启用特定内核参数。
  • ARM CPU:缓存事件的命名和编码逻辑与x86差异很大,需参考对应架构的perf官方文档。

如果硬件不支持标准的PERF_COUNT_HW_CACHE_OP_WRITE/PREFETCH,可以改用raw事件。比如Intel CPU统计L1D写入的示例:

attr1.type = PERF_TYPE_RAW;
attr1.config = 0x28; // 对应L1D_STORES,编码需根据CPU型号调整

4. 确认内核版本与权限

  • 确保内核版本≥3.10,早期内核对PERF_TYPE_HW_CACHE的支持不完善。
  • 运行程序时需要足够权限:要么以root用户运行,要么调整系统参数:
echo 1 | sudo tee /proc/sys/kernel/perf_event_paranoid

关键注意点

  • 必须初始化perf_event_attr结构体并设置attr.size,内核会严格校验该字段,缺失会直接返回EINVAL。
  • 预取事件的支持非常有限,大部分CPU不会单独统计预取的缓存访问/缺失,只能通过监控预取器相关的raw事件近似统计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:03:14