Intel PCM需手动编译安装,编译时需指定-I./cpp -L./build并链接-lpcm,运行前设LD_LIBRARY_PATH=./build;须sudo权限、加载msr模块、禁用虚拟化,且需用pcm-core.x验证硬件支持。

pcm-core.cpp 编译失败:找不到 pcm-core.h 或链接 libpcm.so
Intel PCM 不是系统自带库,必须手动编译安装后才能在 C++ 项目中调用。常见错误是直接 #include <pcm-core.h> 就编译,结果报“no such file”或“undefined reference to PCM::getInstance”。
- 先去 GitHub opcm/pcm 克隆最新代码,进入目录后运行
make(需装好g++、make、cmake) -
make成功后,头文件在./cpp/下,动态库生成在./build/libpcm.so(不是系统路径) - 编译你的程序时得显式指定路径:
g++ -I./cpp -L./build your_app.cpp -lpcm -o your_app - 运行前要设
LD_LIBRARY_PATH=./build,否则libpcm.so找不到
初始化 PCM::getInstance() 返回 nullptr:权限或内核模块问题
Intel PCM 需要读取 MSR 寄存器,普通用户默认无权访问。即使编译通过,PCM::getInstance() 也可能返回 nullptr,且不报错——这是最隐蔽的坑。
- 确认已加载
msr内核模块:lsmod | grep msr;没输出就运行sudo modprobe msr - 运行你的程序必须加
sudo,否则PCM::getInstance()内部检测到权限不足会静默失败 - 某些发行版(如 Ubuntu 22.04+)默认禁用 MSR 访问,需检查
/sys/module/msr/parameters/enabled是否为Y - 虚拟机里基本不可用——KVM/VirtualBox 默认屏蔽 MSR 读取,别白费时间调试
systemCounter->program() 失败:CPU 型号不支持或计数器被占用
调用 program() 是启动采样的关键一步,失败常表现为返回值非 0,但错误码含义模糊。
- 先用
./pcm-core.x -v(PCM 自带工具)验证硬件支持:它能跑通,说明 CPU 型号在 PCM 支持列表内(如 Skylake 及更新架构基本 OK,老 Atom 可能不行) - 同一台机器上不能多个进程同时调用
program()——PCM 占用固定性能计数器资源,第二个调用会因资源冲突失败 - 部分笔记本 CPU 在降频/节能状态下可能拒绝编程计数器,可尝试插电 + BIOS 关闭 C-states 测试
- 返回
-1通常是权限或模块问题;返回-2多为 CPU 不支持或计数器被占;返回-3往往是内核版本太旧(PCM 要求 Linux ≥ 3.10)
采样间隔不准、数据跳变:没调用 sleep() 或忽略 getNumOnlineCores()
PCM 本身不提供定时循环,你得自己控制采样节奏。新手常写成“采集一次就退出”,或用 std::this_thread::sleep_for() 但单位搞错,导致数据毫无规律。
立即学习“C++免费学习笔记(深入)”;
- 采样周期建议 ≥ 100ms,太短会导致计数器溢出或系统开销反超观测目标
- 别直接用
sleep(1)——sleep()是秒级,usleep()已废弃,推荐std::this_thread::sleep_for(std::chrono::milliseconds(500)) - 多核场景下,
getNumOnlineCores()返回的是当前在线逻辑核数,不是物理核数;遍历 core ID 时务必用它做上界,硬写0..31在笔记本上大概率越界 - 每次
update()后,记得用getCoreCounterState(i)拿对应核的数据,别复用同一个对象——不同核状态独立
sudo、漏载 msr 模块、或在 VM 里试,就卡在第一步不动。真要用,先跑通 pcm-core.x,再动自己的 C++ 程序。



















