perf_event_open - 监控多个事件时限制

问题描述 投票:0回答:1

有谁知道我们可以在单个组中监视

PERF_TYPE_HARDWARE
事件的数量是否有限制
PERF_FORMAT_GROUP

我正在尝试监视多个事件,我发现我能够监视 5 个事件,但是当我添加第 6 个硬件事件时,所有已注册事件的值都不会更新。

struct read_format {
  uint64_t nr;          /* The number of events */
  struct {
    uint64_t value;     /* The value of the event */
    uint64_t id;        /* if PERF_FORMAT_ID */
  } values[nr];
};

int main() {
  struct perf_event_attr attr1;
  attr1.type = PERF_TYPE_HARDWARE;
  attr1.config = PERF_COUNT_HW_CPU_CYCLES;
  attr1.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
  int main_fd = syscall(__NR_perf_event_open, &attr1, 0, -1, -1, 0);
  uint64_t id1;
  ioctl(main_fd, PERF_EVENT_IOC_ID, &id1);
  ioctl(main_fd, PERF_EVENT_IOC_RESET, 0);
  ioctl(main_fd, PERF_EVENT_IOC_ENABLE, 0);

  struct perf_event_attr attr2;
  attr2.type = PERF_TYPE_HARDWARE;
  attr2.config = PERF_COUNT_HW_CACHE_REFERENCES;
  attr2.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
  int fd2 = syscall(__NR_perf_event_open, &attr2, 0, -1, main_fd, 0);
  uint64_t id2;
  ioctl(fd2, PERF_EVENT_IOC_ID, &id2);
  ioctl(fd2, PERF_EVENT_IOC_RESET, 0);
  ioctl(fd2, PERF_EVENT_IOC_ENABLE, 0);

  /*
  commenting out attr3 through attr 7. They are the same as attr2 except the following config:
  attr3.config = PERF_COUNT_HW_CACHE_MISSES;
  attr4.config = PERF_COUNT_HW_BRANCH_MISSES;
  attr5.config = PERF_COUNT_HW_BUS_CYCLES;
  attr6.config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND;
  attr7.config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND;
  */

  // read_values and log "START"

  // action

  // read_values and log "END"

  return 0;
}

read_values() {
  char buffer[4096];
  int read_bytes = read(main_fd, &buffer, sizeof(buffer));
  if (read_bytes == -1) { return 1; }

  struct read_format* rf = (struct read_format*) buffer;
  int values[rf->nr];
  for (int i=0; i<rf->nr; i++) {
    values[i] = rf->values[i].value;
  }
}

在上面的代码中,当我只为 attr1 - 5 打开 perf 事件时,“START”和“END”处的所有记录值都已更新。但是,当我尝试为 6 个事件(或所有 7 个硬件事件)打开 perf 事件时,“开始”和“结束”处的所有记录值保持完全相同。

如果我直接阅读每个事件,我就能获得所有 7 个事件的值:

int fd2 = syscall(__NR_perf_event_open, &attr2, 0, -1, -1 /*!!instead of main_fd!!*/, 0);
,然后对每个
read()
执行
fd
。但是为了减少
read
调用的次数,我更愿意从
main_fd
中读取并从那里获取值。单次
PERF_FORMAT_GROUP
捕获的硬件事件数量是否有限制?我注意到第 6 个和第 7 个事件是否是我没有看到此问题的软件事件。

非常感谢任何意见。谢谢!

c linux profiling perf
1个回答
0
投票

当我走进兔子洞并遇到这篇文章时,我想我会发布我自己的问题的答案。根据“事件组”部分:

可用性能计数器的数量取决于 CPU。一个组不能包含 比可用计数器更多的事件。例如 Intel Core CPU 通常有四个 核心的通用性能计数器,加上三个固定的指令计数器, 循环和参考循环。一些特殊事件对他们可以使用的柜台有限制 计划,并且可能不支持单个组中的多个实例。事件过多时 在组中指定其中一些将不会被测量。

© www.soinside.com 2019 - 2024. All rights reserved.