我正在尝试使用perf
. 尽管在下面的代码中确实出现了,即使pid
参数perf_event_open
是0
(这应该导致整个进程的分析?),硬件计数器值仅对应于执行线程(与 perf 计数器在线程中求和)过程)inf_loop
不被计算在内。
我的问题是:如何分析进程中的所有线程与仅执行perf_event_open
如下的线程?perf_event_attr
是否需要设置其他配置以启用进程范围的分析?
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
{
int ret;
ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
group_fd, flags);
return ret;
}
static int fd;
void setup()
{
struct perf_event_attr pe;
memset(&pe, 0, sizeof(pe));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof(pe);
pe.config = PERF_COUNT_HW_INSTRUCTIONS;
pe.disabled = 1;
pe.exclude_kernel = 1;
pe.exclude_hv = 1;
pid_t pid = 0;
int cpu = -1;
fd = perf_event_open(&pe, pid, cpu, -1, 0);
if (fd == -1) {
fprintf(stderr, "Error opening leader %llx\n", pe.config);
exit(EXIT_FAILURE);
}
ioctl(fd, PERF_EVENT_IOC_RESET, 0);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
}
int64_t read()
{
int64_t count;
read(fd, &count, sizeof(count));
return count;
}
std::size_t k;
// The instruction counts do not reflect the cycles consumed here
void inf_loop()
{
k = 2;
volatile size_t *p = &k;
while (*p)
{
++k;
}
}
int main(int argc, char **argv)
{
setup();
thread t1(inf_loop);
int count = 0;
for (uint64_t idx = 0; idx < (1ULL << 54); ++idx)
{
if (idx % (1ULL << 32) == 0)
{
cout << "Cycles: " << read() << endl;
}
}
}