如何在CentOS 7(3.10内核)上让perf支持i9-10900K的L1-dcache-stores事件?
你遇到的问题确实是因为CentOS 7默认的3.10内核发布时间早于10代Intel Comet Lake处理器(比如i9-10900K),完全没有针对这款CPU的性能监控单元(PMU)做适配,而perf工具的事件支持高度依赖内核提供的硬件抽象层。以下是几个可行的解决办法:
方案1:升级CentOS 7的内核到支持新CPU的版本
这是最彻底的解决方案,新内核会完整适配Comet Lake的性能计数器。推荐使用ELRepo提供的主线稳定内核(kernel-ml),步骤如下:
- 安装ELRepo仓库:
sudo rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org sudo rpm -Uvh https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm - 安装主线稳定内核:
sudo yum --enablerepo=elrepo-kernel install kernel-ml - 重启系统,在GRUB菜单中选择新安装的内核(默认会自动优先启动最高版本的内核)
- 安装对应版本的perf工具:
sudo yum --enablerepo=elrepo-kernel install kernel-ml-tools
之后再执行perf stat -e L1-dcache-stores echo就应该正常工作了。这个方案的优点是能完整支持所有CPU性能事件,缺点是需要重启系统,且新内核可能和部分旧版系统组件存在微小兼容性风险(不过kernel-ml已经经过大量测试,稳定性有保障)。
方案2:手动编译最新版perf工具
如果不想升级整个内核,可以尝试编译较新的perf工具(来自Linux内核源码),新版perf能识别更多新CPU的事件定义。步骤如下:
- 安装编译依赖:
sudo yum install gcc git make elfutils-libelf-devel libcap-devel - 克隆最新的稳定版内核源码(推荐选择5.x或6.x分支,对应Comet Lake发布后的版本):
git clone --depth=1 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git -b v6.1 - 进入perf目录并编译:
cd linux/tools/perf make - 编译完成后,直接使用当前目录下的
perf二进制文件:sudo ./perf stat -e L1-dcache-stores echo
注意:这种方式下,perf的部分高级功能可能受限于旧内核,但基本的性能事件统计(比如L1缓存事件)通常可以正常工作,因为perf会直接和硬件PMU交互,只要事件定义正确即可。
方案3:使用原始性能事件编码
如果上述两种方案都无法实施,可以通过指定原始事件编码来绕过内核事件定义的限制。步骤如下:
- 在CentOS 8系统上,查询
L1-dcache-stores对应的原始编码:
输出通常会显示类似perf list L1-dcache-storesL1-dcache-stores [Hardware event],同时可能附带原始编码(比如r04,具体编码取决于CPU型号)。 - 在CentOS 7系统上,使用这个原始编码执行perf命令:
sudo perf stat -e rXXXX echo # 替换XXXX为你查到的编码
你也可以直接查阅Intel官方的《Software Developer Manual》(SDM)卷3的性能监控部分,找到Comet Lake处理器对应的L1数据缓存存储事件的原始MSR编码。这个方案的优点是不需要修改系统或编译工具,缺点是事件名称不直观,且需要手动查找编码。
内容的提问来源于stack exchange,提问作者Joshua Chia

