perf_event_open - 如何监视多个事件

2024-02-04

有谁知道如何设置perf_event_attr可以通过以下方式触发 PMU 监视多个(类型)事件的结构perf_event_open()?

Like perf record -e cycles,faults ls,它有两种不同的事件类型(PERF_TYPE_HARDWARE 和 PERF_TYPE_SOFTWARE),但在示例中perf_event_open 手册页 http://www.man7.org/linux/man-pages/man2/perf_event_open.2.html, perf_event_attr.type只能分配单个值。

任何建议将不胜感激,谢谢!

20170208更新感谢@gudok为我指明了方向,但结果似乎有些异常。 演示程序如下(用于测量整个系统的CPU周期和缓存未命中):

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
#include <asm/unistd.h>
#include <errno.h>
#include <stdint.h>
#include <inttypes.h>
#include <time.h>

struct read_format {
  uint64_t nr;
  struct {
    uint64_t value;
    uint64_t id;
  } values[];
};

int main(int argc, char* argv[]) {
  struct perf_event_attr pea;
  int fd1, fd2;
  uint64_t id1, id2;
  uint64_t val1, val2;
  char buf[4096];
  struct read_format* rf = (struct read_format*) buf;
  int i,j;
  struct timespec time, time2;

  time.tv_sec = 1;
  time.tv_nsec = 0;

  memset(&pea, 0, sizeof(struct perf_event_attr));
  pea.type = PERF_TYPE_HARDWARE;
  pea.size = sizeof(struct perf_event_attr);
  pea.config = PERF_COUNT_HW_CPU_CYCLES;
  pea.disabled = 1;
  pea.exclude_kernel = 1;
  pea.exclude_hv = 1;
  pea.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
  fd1 = syscall(__NR_perf_event_open, &pea, 0, -1, -1, 0);
  ioctl(fd1, PERF_EVENT_IOC_ID, &id1);

  memset(&pea, 0, sizeof(struct perf_event_attr));
  pea.type = PERF_TYPE_HARDWARE;
  pea.size = sizeof(struct perf_event_attr);
  pea.config = PERF_COUNT_HW_CACHE_MISSES;
  pea.disabled = 1;
  pea.exclude_kernel = 1;
  pea.exclude_hv = 1;
  pea.precise_ip = 2;  // want to using PEBS 
  pea.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
  fd2 = syscall(__NR_perf_event_open, &pea, 0, -1, fd1 /*!!!*/, 0);
  ioctl(fd2, PERF_EVENT_IOC_ID, &id2);

  ioctl(fd1, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
  ioctl(fd1, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
  while (1) {
    nanosleep(&time, &time2);

    //ioctl(fd1, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP);

    read(fd1, buf, sizeof(buf));
    for (i = 0; i < rf->nr; i++) {
      if (rf->values[i].id == id1) {
        val1 = rf->values[i].value;
      } else if (rf->values[i].id == id2) {
        val2 = rf->values[i].value;
      }
    }

    printf("cpu cycles: %"PRIu64"\n", val1);
    printf("cache misses: %"PRIu64"\n", val2);

  }

  return 0;
}

输出是:

cpu cycles: 120   // Just have about 120 CPU cycles in a second
cache misses: 0   // and doesn't have any cache miss?
cpu cycles: 233
cache misses: 0
cpu cycles: 352
cache misses: 0
cpu cycles: 455
cache misses: 0
cpu cycles: 562
cache misses: 0
cpu cycles: 673
cache misses: 0
cpu cycles: 794
cache misses: 0
cpu cycles: 907
cache misses: 0
cpu cycles: 1011
cache misses: 0
cpu cycles: 1129
cache misses: 3
cpu cycles: 1269
cache misses: 4
cpu cycles: 1423

这有点棘手。

我们像往常一样创建第一个计数器。另外,我们通过PERF_FORMAT_GROUP and PERF_FORMAT_ID能够同时与多个计数器一起工作。这个柜台将是我们的组长。

struct perf_event_attr pea;
int fd1, fd2;
uint64_t id1, id2; 

memset(&pea, 0, sizeof(struct perf_event_attr));
pea.type = PERF_TYPE_HARDWARE;
pea.size = sizeof(struct perf_event_attr);
pea.config = PERF_COUNT_HW_CPU_CYCLES;
pea.disabled = 1;
pea.exclude_kernel = 1;
pea.exclude_hv = 1;
pea.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
fd1 = syscall(__NR_perf_event_open, &pea, 0, -1, -1, 0);

接下来,我们检索第一个计数器的标识符:

ioctl(fd1, PERF_EVENT_IOC_ID, &id1);

第二个(以及所有其他计数器)以相同的方式创建,只有一个例外:我们通过fd1作为小组领导者的价值论点:

memset(&pea, 0, sizeof(struct perf_event_attr));
pea.type = PERF_TYPE_SOFTWARE;
pea.size = sizeof(struct perf_event_attr);
pea.config = PERF_COUNT_SW_PAGE_FAULTS;
pea.disabled = 1;
pea.exclude_kernel = 1;
pea.exclude_hv = 1;
pea.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
fd2 = syscall(__NR_perf_event_open, &pea, 0, -1, fd1, 0); // <-- here
ioctl(fd2, PERF_EVENT_IOC_ID, &id2);

接下来我们需要声明一个数据结构来一次读取多个计数器。您必须根据传递给的标志声明不同的字段集perf_event_open。手册页提到了所有可能的字段。在我们的例子中,我们通过了PERF_FORMAT_ID添加的标志id场地。这将使我们能够区分不同的计数器。

struct read_format {
    uint64_t nr;
    struct {
        uint64_t value;
        uint64_t id;
    } values[/*2*/];
};

现在我们调用标准分析 ioctl:

ioctl(fd1, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
ioctl(fd1, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
do_something();
ioctl(fd1, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP);

最后,我们从组领导文件描述符中读取计数器。两个计数器均以单个形式返回read_format我们声明的结构:

char buf[4096];
struct read_format* rf = (struct read_format*) buf;
uint64_t val1, val2;

read(fd1, buf, sizeof(buf));
for (i = 0; i < rf->nr; i++) {
  if (rf->values[i].id == id1) {
    val1 = rf->values[i].value;
  } else if (rf->values[i].id == id2) {
    val2 = rf->values[i].value;
  }
}
printf("cpu cycles: %"PRIu64"\n", val1);
printf("page faults: %"PRIu64"\n", val2);

以下是完整的程序清单:

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
#include <asm/unistd.h>
#include <errno.h>
#include <stdint.h>
#include <inttypes.h>

struct read_format {
  uint64_t nr;
  struct {
    uint64_t value;
    uint64_t id;
  } values[];
};

void do_something() {
  int i;
  char* ptr;

  ptr = malloc(100*1024*1024);
  for (i = 0; i < 100*1024*1024; i++) {
    ptr[i] = (char) (i & 0xff); // pagefault
  }
  free(ptr);
}

int main(int argc, char* argv[]) {
  struct perf_event_attr pea;
  int fd1, fd2;
  uint64_t id1, id2;
  uint64_t val1, val2;
  char buf[4096];
  struct read_format* rf = (struct read_format*) buf;
  int i;

  memset(&pea, 0, sizeof(struct perf_event_attr));
  pea.type = PERF_TYPE_HARDWARE;
  pea.size = sizeof(struct perf_event_attr);
  pea.config = PERF_COUNT_HW_CPU_CYCLES;
  pea.disabled = 1;
  pea.exclude_kernel = 1;
  pea.exclude_hv = 1;
  pea.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
  fd1 = syscall(__NR_perf_event_open, &pea, 0, -1, -1, 0);
  ioctl(fd1, PERF_EVENT_IOC_ID, &id1);

  memset(&pea, 0, sizeof(struct perf_event_attr));
  pea.type = PERF_TYPE_SOFTWARE;
  pea.size = sizeof(struct perf_event_attr);
  pea.config = PERF_COUNT_SW_PAGE_FAULTS;
  pea.disabled = 1;
  pea.exclude_kernel = 1;
  pea.exclude_hv = 1;
  pea.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
  fd2 = syscall(__NR_perf_event_open, &pea, 0, -1, fd1 /*!!!*/, 0);
  ioctl(fd2, PERF_EVENT_IOC_ID, &id2);


  ioctl(fd1, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
  ioctl(fd1, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
  do_something();
  ioctl(fd1, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP);


  read(fd1, buf, sizeof(buf));
  for (i = 0; i < rf->nr; i++) {
    if (rf->values[i].id == id1) {
      val1 = rf->values[i].value;
    } else if (rf->values[i].id == id2) {
      val2 = rf->values[i].value;
    }
  }

  printf("cpu cycles: %"PRIu64"\n", val1);
  printf("page faults: %"PRIu64"\n", val2);

  return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

perf_event_open - 如何监视多个事件 的相关文章

  • C++ 模板中的名称查找

    我有一些 C 代码 如果没有 fpermissive 选项 就无法再编译 这是我无法分享的专有代码 但我认为我已经能够提取一个简单的测试用例来演示该问题 这是 g 的输出 template eg cpp In instantiation o
  • 避免集合已修改错误

    Issue 我有以下代码 foreach var ItemA in GenericListInstanceB ItemA MethodThatCouldRemoveAnyItemInGenericListInstanceB 显然我得到一个错
  • 如何“杀死”Pthread?

    我正在学习 Pthreads 并且想知道杀死这样一个对象的最佳方法是什么 在寻找类似的问题后 我无法找到 明确 的答案 但请随时向我指出任何相关问题 我正在使用一个小型客户端服务器应用程序 其中服务器主线程正在侦听套接字上的客户端连接 每次
  • C++ 私有静态成员变量

    此 C 代码在编译时产生链接器错误 A h class A public static void f private static std vector
  • async wait 在调用异步方法时返回 Task> 而不是 List

    我正在尝试了解 async wait 的用法 并且研究了一些博客文章 现在我已经编写了一个测试代码 但它没有按照我期望的方式工作 我有一个返回列表的方法 private List
  • 正则表达式删除某些字符周围不需要的空格

    我正在尝试从 JavaScript 文件中删除一些不需要的空格 并在将文件发送到客户端之前使用 C 和 Regex 组合文件 我有一个JavascriptHandler处理 js 文件 效果很好 这是我用来 打包 JavaScript 的函
  • 获取给定EntityType的导航属性

    我在用VS2010 EF4 0 需要如下功能 private string GetNaviProps Type entityType eg typeof Employee NorthwindEntities en new Northwind
  • 无法仅在控制台中启动 androidstudio

    你好 我的问题是下一个 我下载了Android Studio如果我去 路径 android studio bin 我执行studio sh 我收到以下错误 No JDK found Please validate either STUDIO
  • 枚举器上的 [[maybe_unused]]

    查看规格 maybe unused http en cppreference com w cpp language attributes 它指出 出现在类 typedef 变量 非静态数据成员 函数 枚举或枚举器的声明中 如果编译器对未使用
  • 套接字:监听积压并接受

    listen sock backlog 在我看来 参数backlog限制连接数量 这是我的测试代码 server initialize the sockaddr of server server sin family AF INET ser
  • Create CFrameWnd 给出了第一次机会异常——为什么?

    我正在尝试使用基于 CFrameWnd 的代码编写一个简单的 MFC 应用程序 该应用程序在可滚动窗口中绘制 下面的代码改编自 Prosise Programming Windows with MFC 第 2 版 第 89ff 页 当我在调
  • 在不使用 Thread.Sleep c# 的情况下延迟发送电子邮件

    我有一个 for 循环 它循环并每个循环发送一封电子邮件 现在我正在使用 thread sleep 但我希望用户仍然能够与程序交互 只需取消该循环即可 是否可以在不使用 thread sleep 的情况下做到这一点 您是否在 UI 线程上运
  • .Net Core 中的脚手架以及解决方案中的多个项目

    我创建了一个针对 net461 的 Net Core MVC6 应用程序 我使用了一个我非常熟悉的项目结构 其中我将数据 模型和服务类放置在单独的类库项目中 并且 Web 项目引用这些项目 当我尝试搭建控制器时 我收到一条错误 指出我正在搭
  • 无法将方法组“Read”转换为非委托类型“bool”

    我正在尝试使用SqlDataReader检查条目是否存在 如果存在则返回ID 否则返回false 当我尝试编译时 出现错误 无法将方法组 Read 转换为非委托类型 bool 我一直在遵循在 VB 中找到的示例 但似乎翻译可能不正确 pri
  • 如何查明 Ubuntu 上安装了哪个版本的 GTK+?

    我需要确定 Ubuntu 上安装了哪个版本的 GTK 男人似乎不帮忙 这个建议 https stackoverflow com a 126145 会告诉您安装了哪个 2 0 的次要版本 不同的主要版本将具有不同的包名称 因为它们可以在系统上
  • 需要使用 openssl 加密和解密文件的示例 C 代码

    我正在用 Linux C 编写代码 我需要使用以下命令来加密和解密文件 openssl 目前 我使用系统命令 des3 e nosalt k 0123456789012345 in inp file out out file 进行加密 使用
  • 在 try catch 块中返回到 catch 内是否不好?这是很好的做法

    在 try catch 块中从 C 中的 catch 块返回值是不好的做法吗 try Some code return 1 catch return 0 哪种使用 try catch 的方法是好的做法 不需要 只要返回的值是你想要的 你可以
  • 在代码中而不是 XAML 中呈现 UserControl

    我想用RenderTargetBitmap将 UserControl 呈现为位图 而无需为其编写 XAML 当我这样做时 我得到一张空白图像 我是否错过了关键的一步 ValTool Controls VideoFisheyeOverlayC
  • 致命错误 C1001:编译器中发生内部错误(编译器文件“msc1.cpp”,第 1325 行)

    当我编译代码时 错误指向以下类 该错误在两行上突出显示 如下所示 tm validFrom tm validUntil struct t SslCertData final struct t Contact TCHAR Organizati
  • 如何将 char 转换为 unsigned int?

    我有一个字符数组 它实际上用作字节数组 而不是用于存储文本 在数组中 有两个特定字节表示我需要存储到无符号 int 值中的数值 下面的代码解释了设置 char bytes bytes 2 bytes 0 0x0C For the sake

随机推荐

  • 使用extjs有什么优点和缺点? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Webpack:如何覆盖 package.json 主字段?

    如何像 Bower 中那样覆盖 package json 的主字段 overrides highcharts main highcharts js 尝试创建一个与 Webpack 配置中的模块同名的别名 module exports res
  • 基于注释的 Spring bean 验证

    我正在研究一种基于注释的方法来验证 Spring bean弹簧模块 https springmodules dev java net In 本教程 http wheelersoftware com articles spring bean
  • SHA256 给出 44 长度输出而不是 64 长度

    我正在使用以下代码来执行 SHA256 public static string GenerateSaltedHash string plainTextString string saltString byte salt Encoding
  • 如果整数以前导零开头,为什么 JSON 无效?

    我正在将一些 JSON 文件导入到 Parse com 项目中 但不断收到错误 无效的键 值对 它指出有一个意想不到的 8 这是我的 JSON 的示例 Manufacturer Manufacturer Model THIS IS A ST
  • 使用某些 Object 属性从 ArrayList 中删除对象

    我正在维护一个ArrayList的物体 我的对象结构是 ID 名称和其他一些详细信息 我需要删除一个具有某个 id 值 10 的对象 并且我不想迭代该列表 有什么解决办法吗 使用 Java 8Collection removeIf http
  • 如何在Linux上创建临时文件,无论发生什么情况都会自动清理?

    我想在Linux上创建一个临时文件 同时确保该文件在我的程序终止后会消失 即使它被杀死或有人在错误的时刻执行了硬重启 做tmpfile 为我处理这一切 您似乎全神贯注于文件可能会因为某些原因而被遗忘的想法竞争条件 我没有看到为什么这是一个问
  • 配置 StructureMap.MVC5 与 Identity 配合使用的问题

    我目前正在尝试在从一开始就从未正确实现的旧版本 2 6 升级后在我们的应用程序中重新配置 StructureMap 我刚开始使用 DI 容器 并且发现很难找到较新的 StructureMap 版本的文档 我卸载了旧的 2 6 版本的 Str
  • 如何使用 JavaScript 和 sha512 算法对字符串进行哈希处理

    我尝试过使用 NPM 中的 sha512 但它一直在散列错误的内容 即我应该获取一个字符串 但它一直返回对象 所以在 PHP 中我知道我可以执行任务 hash hash sha512 my string for hashing 如何在 No
  • 安装自定义 Visual Studio 语言服务

    我按照一篇非常有用的文章的指示 为我的软件工作室的内部脚本语言编写了一个新的 Visual Studio 语言服务编写您的第一个 Visual Studio 语言服务 http www codeproject com KB recipes
  • 通过 dplyr 中的动态列名进行汇总

    所以我试图在 dplyr 中进行一些编程 但我在 enquo 和 评价 基本上我想将列更改为动态列名称 然后能够进一步操作该列 即汇总 例如 my function lt function data column quo column lt
  • 在 Visual Studio 2010 中显示当前行号和列号

    我刚刚安装了 SP1 现在在 Visual Studio 中的每个源文件底部看不到文本编辑器行号和列号 有谁知道如何重新打开此功能 如果使用 16 4 x 或更高版本的人想知道它去了哪里 它已从状态栏移动到编辑器窗口的右下角 请注意Col当
  • 如何对文档进行部分更新

    我需要有关如何更新 CouchDB 中的字段的指导 我通过控制台尝试了curl 它工作正常 但是以编程方式 我不明白如何更新特定字段 例如 名称 这是在 CouchDB 中更新文档的片段 它工作正常并返回更新后的修订 ID HttpPut
  • 如何在 Cocoa 应用程序中包含 OpenCV?

    当我使用 命令行工具 c stdc 模板创建 xCode 项目时 我能够包含并编译 opencv 标头并运行一些代码 但我想在 Cocoa 应用程序 上下文中使用 OpenCV 使用该模板创建时 当我在 main mm 中包含 OpenCV
  • 如何以编程方式设置gridview的高度android

    我想设置我的高度Gridview在我的应用程序中以编程方式 有什么办法可以实现吗 我只想在代码中的两种特殊情况下更改 gridview 高度 EDIT
  • 如何在 MapView 下方添加 TextView?

    我跟着你好视图 谷歌地图视图 http developer android com resources tutorials views hello mapview html现在我想添加一个TextView在下面的MapView 我只更改了布
  • Git 日志不显示子模块更改[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我在 ma
  • 更改react-big-calendar事件的颜色

    I need to make a calendar with events and I decided to use react big calendar http intljusticemission github io react bi
  • CSS 变换原点不适用于 safari 中的 svg

    我正在尝试围绕其中心旋转图像 但在Safari中 SVG的左上角 总是以它的原点为中心进行旋转 var rotate val 30 function rotate val rotate val rotate val val var tran
  • perf_event_open - 如何监视多个事件

    有谁知道如何设置perf event attr可以通过以下方式触发 PMU 监视多个 类型 事件的结构perf event open Like perf record e cycles faults ls 它有两种不同的事件类型 PERF