【发布时间】:2021-01-12 12:29:03
【问题描述】:
前段时间,我问了以下问题"How to count number of executed instructions of a process id including child processes",@M-Iduoad 提供了一个解决方案,pgrep 捕获所有子 PID,并在 perf stat 中与 -p 一起使用。效果很好!
但是,我遇到的一个问题是多线程应用程序,以及何时产生新线程。由于我不是算命先生(太糟糕了!),我不知道tid 新生成的线程,因此我无法将它们添加到perf stat 的-p 或-t 参数中。
作为示例,假设我有一个多线程 nodejs 服务器(部署为 Kubernetes 之上的容器),带有以下 pstree:
root@node2:/home/m# pstree -p 4037791
node(4037791)─┬─sh(4037824)───node(4037825)─┬─{node}(4037826)
│ ├─{node}(4037827)
│ ├─{node}(4037828)
│ ├─{node}(4037829)
│ ├─{node}(4037830)
│ └─{node}(4037831)
├─{node}(4037805)
├─{node}(4037806)
├─{node}(4037807)
├─{node}(4037808)
├─{node}(4037809)
├─{node}(4037810)
├─{node}(4037811)
├─{node}(4037812)
├─{node}(4037813)
└─{node}(4037814)
当然,我可以使用下面的perf stat 命令来查看它的线程:
perf stat --per-thread -e instructions,cycles,task-clock,cpu-clock,cpu-migrations,context-switches,cache-misses,duration_time -p $(pgrep --ns 4037791 | paste -s -d ",")
它适用于单线程 nodejs 应用程序。但在多线程服务的情况下,一旦收到请求,pstree 的输出将如下所示:
root@node2:/home/m# pstree -p 4037791
node(4037791)─┬─sh(4037824)───node(4037825)─┬─{node}(4037826)
│ ├─{node}(4037827)
│ ├─{node}(4037828)
│ ├─{node}(4037829)
│ ├─{node}(4037830)
│ ├─{node}(4037831)
│ ├─{node}(1047898)
│ ├─{node}(1047899)
│ ├─{node}(1047900)
│ ├─{node}(1047901)
│ ├─{node}(1047902)
│ ├─{node}(1047903)
│ ├─{node}(1047904)
│ ├─{node}(1047905)
│ ├─{node}(1047906)
│ ├─{node}(1047907)
│ ├─{node}(1047908)
│ ├─{node}(1047909)
│ ├─{node}(1047910)
│ ├─{node}(1047911)
│ ├─{node}(1047913)
│ ├─{node}(1047914)
│ ├─{node}(1047919)
│ ├─{node}(1047920)
│ ├─{node}(1047921)
│ └─{node}(1047922)
├─{node}(4037805)
├─{node}(4037806)
├─{node}(4037807)
├─{node}(4037808)
├─{node}(4037809)
├─{node}(4037810)
├─{node}(4037811)
├─{node}(4037812)
├─{node}(4037813)
└─{node}(4037814)
因此,我之前的perf stat 命令不会捕获新生成线程的统计信息。我的意思是,它可能会捕获累积的指令,但绝对不会以“每线程”格式显示。
有什么方法可以在 perf stat 中使用--per-thread 并捕获多线程应用程序中新产生的线程的统计信息?它似乎只与-p 或-t 一起工作,以跟随perf 启动时已经存在的一组固定线程,并且不会跟随新线程。
有一个类似的question here for perf record,但我使用的是perf stat。另外,这似乎并没有将记录的配置文件按线程分开,所以它仅相当于perf stat node ... 除非有办法处理记录的数据以在事后按线程将其分开?
perf 不是必需的,如果还有其他方法可以使用:
任何其他可以帮助我动态计算给定 PID 的每个线程(包括新生成的线程)的“指令、周期、任务时钟、cpu 时钟、cpu 迁移、上下文切换、缓存未命中”的潜在解决方案是可以接受,无论是使用perf 还是其他任何东西!
【问题讨论】:
-
perf stat没有-p会跟踪所有线程。例如perf stat node foo.js,与链接的perf record问题相同。当您使用-p而不是将命令作为perf的子级运行时,您的问题是要执行什么操作。 -
@PeterCordes 我在没有 -p 和 --per-thread 的情况下尝试过,但是在 perf start 之后它仍然没有报告新的分叉/派生线程 :-( ...换句话说,继承模式似乎离开
-
perf stat ffmpeg -i foo.mkv bar.mkv为我工作。我看到了190,958.96 msec task-clock # 7.027 CPUs utilized(在我的 4c8t Skylake 系统上),挂钟时间经过了 27.17 秒。 (在按下q提前停止之后。)对于硬件事件,其他计数反映了由 FFmpeg、libx264 和音频编码启动的所有线程的计数。 -
好吧,我害怕那个; can "perf record" or "perf-record" sample child processes? 您链接的 不是 实际上是您想要的性能记录等价物。因此,仅仅为
perf record服务并不是这与您的问题之间的唯一区别。 -
您是否尝试过
perf record和-s包含每个线程的统计信息,然后使用perf report -T读取 perf.data 您将在底部获得一个包含线程及其统计信息的表格.
标签: linux performance profiling performance-testing perf