我正在尝试访问大型复杂应用程序中的性能计数器。但是当我读取结果时,它总是返回 0。我还启用了总运行时间和总启用时间,它们都返回 0。下面列出了我为此使用的代码:
perf_event_attr PerfEvent;
std::memset(&PerfEvent, 0, sizeof(PerfEvent));
PerfEvent.type = PERF_TYPE_HARDWARE;
PerfEvent.disabled = 0;
PerfEvent.pinned = 1;
PerfEvent.inherit = 1;
PerfEvent.config = PERF_COUNT_HW_CPU_CYCLES;
PerfEvent.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING;
int fd = syscall(__NR_perf_event_open, &PerfEvent, getpid(), -1, -1, 0);
// Code to profile
uint64_t RetVal[3];
const int32_t rc = read(fd, &RetVal, sizeof(RetVal));
close(fd);
我还确保应用程序具有以下功能:CAP_PERFMON 和 CAP_SYS_ADMIN。我什至编写了一个小函数来在应用程序本身中检查这一点。
const bool IsCapabilitySet(int Capability){
if(!cap_valid(Capability)){
std::cout << "ERROR: Capability is not valid\n";
return false;
}
return (prctl(PR_CAPBSET_READ, Capability) == 1);
}
最重要的是
/proc/sys/kernel/perf_event_paranoid
设置为 0。
当我在同一系统上的一个非常简单的应用程序中使用上面的代码时,它返回正确的性能计数器。
如何解决这个问题?在 Linux 代码库中哪里可以找到更新这些性能计数器的代码?
请尝试使用标准
perf
实用程序来读取至少一些计数器并查看是否成功。
此外,如果您使用虚拟化软件,请查看虚拟机管理程序中是否启用了 PMU 虚拟化。