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

指定CPU ID调用perf_event_open()始终返回0的问题

perf_event_open指定CPU后计数器返回0的问题解决

最可能的原因:用了进程ID而非线程ID

你现在传的是getpid()作为perf_event_open的pid参数,但如果要统计单个绑定CPU的线程,必须传线程ID(tid)而不是进程ID。Linux里每个线程有独立的tid,getpid()返回的是整个进程的ID,当你同时指定进程ID和CPU时,内核会统计这个进程下所有线程在该CPU上的事件——但如果你的目标线程是进程里唯一在这个CPU上的线程,内核的匹配逻辑可能出现偏差,导致计数器归零。

要获取线程ID,需要用syscall(SYS_gettid)(glibc没有直接封装gettid(),得包含<sys/syscall.h>和<unistd.h>)。修正后的代码:

#include <sys/syscall.h>
#include <unistd.h>
#include <sched.h>

// ...

// 先确保线程已经绑定到目标CPU,再获取当前CPU
pid_t thread_id = syscall(SYS_gettid);
int target_cpu = sched_getcpu();
fd[0] = perf_event_open(&attr[0], thread_id, target_cpu, -1, 0);

其次要确认CPU绑定的时机

你说已经确认线程前后CPU一致,但一定要保证:先绑定CPU,再调用sched_getcpu()和perf_event_open。如果先获取CPU ID再绑定,拿到的是绑定前的CPU,自然监听不到目标CPU上的事件。另外,在perf事件运行过程中,可以再调用一次sched_getcpu(),确认线程真的没有被调度到其他CPU上。

其他排查方向

  • 试换软件事件测试:有些硬件性能事件可能不支持“特定线程+特定CPU”的组合统计,先换成PERF_COUNT_SW_TASK_CLOCK这类软件事件验证,如果能拿到数据,就是硬件事件的兼容性问题。
  • 检查CPU ID有效性:sched_getcpu()返回的是逻辑CPU ID,要确保它小于sysconf(_SC_NPROCESSORS_ONLN)返回的在线CPU数量,避免传了无效的CPU ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 04:50:19