【问题标题】:Linux Performance Monitoring, any way to monitor per-thread?Linux性能监控,有什么方法可以监控每个线程?
【发布时间】:2015-01-21 02:39:53
【问题描述】:

我正在使用 Linux Ubuntu,并使用 C++ 进行编程。我已经能够使用 perf_event 访问性能计数器(指令计数、缓存未命中等)(实际上是使用此链接中的程序:https://github.com/castl/easyperf)。

但是,现在我正在使用 pthreads 运行多线程应用程序,并且需要分别完成每个线程的指令计数和周期。关于如何解决这个问题的任何想法?

谢谢!

【问题讨论】:

  • 其他问题中的那些分析器似乎不使用 C++。它们是像 Valgrind 这样的工具,开销很大。
  • 您可以尝试更改easyperf中的inherit flag(stackoverflow.com/a/28871708和man perf_event_open)并在线程开始时在每个pthread中启动它。

标签: c++ linux multithreading performance perf


【解决方案1】:

perf 是您可以使用的系统分析工具。它不像https://github.com/castl/easyperf),它是一个库,您可以在代码中使用它。按照这些步骤并使用它来分析您的程序:

  1. 在 Ubuntu 上安装 perf。在不同的 Linux 发行版中,安装可能会有很大的不同。您可以找到安装教程行。

  2. 只需运行程序并获取程序的所有线程 id:

    ps -eLf | grep [application name]

  3. 打开单独的终端并根据手册页以perf stat -t [threadid] 运行 perf:

    usage: perf stat [<options>] [<command>]

    -e, --event <event>   event selector. use 'perf list' to list available events
    -i, --no-inherit      child tasks do not inherit counters
    -p, --pid <n>         stat events on existing process id
    -t, --tid <n>         stat events on existing thread id
    -a, --all-cpus        system-wide collection from all CPUs
    -c, --scale           scale/normalize counters
    -v, --verbose         be more verbose (show counter open errors, etc)
    -r, --repeat <n>      repeat command and print average + stddev (max: 100)
    -n, --null            null run - dont start any counters
    -B, --big-num         print large numbers with thousands' separators
    

有一个关于perfanalysis article,你可以感受一下。

【讨论】:

  • 我正在主函数中创建 pthread。但是, ps -eLf | grep [application name] 给了我这个输出(只显示 1 个线程): 18428 17539 18428 0 1 01:31 pts/0 00:00:00 grep a.out 因此在这种情况下 threadid 也被限制为 0。我认为这个命令是给进程id而不是线程id
  • 表示您的程序已终止。该程序显示有grep,它不是你的程序。您的程序是否作为守护进程运行?
  • 我的可执行文件是 a.out,所以我运行了 ps -eLf | ./a.out 它只是给了我程序输出
  • ./a.out &amp; 运行你的程序,然后运行ps -eLf | grep "a.out"
  • 好的,我运行了 ./a.out & 之后程序在给出输出后仍然运行,然后我运行了第二个命令,它给了我这个输出:maa13033 19215 18763 19215 0 1 01:49 pts/0 00:00:00 grep a.out [1]+ 完成 ./a.out
【解决方案2】:

请查看perf 工具文档here,它支持您要分析的一些事件(例如:instructionscache-misses)。摘自上面链接的 wiki 页面:

perf 工具可用于在每个线程、每个进程、每个 cpu 或系统范围内对事件进行计数。在 per-thread 模式下,计数器仅监视指定线程的执行。当线程被调度出去时,监控停止。当线程从一个处理器迁移到另一个处理器时,计数器会保存在当前处理器上并在新处理器上恢复。

【讨论】:

  • 我认为per thread模式意味着只能监控一个线程,也就是指定线程。每个进程监控进程并给出平均统计数据。
  • @masab 是的。你有什么要求?
  • @qqibrow 如果我有 2 个线程在 2 个内核上同时运行,那么我想知道在这两个内核上执行了多少指令(这给了我 2 个指令计数)。我想查看每个线程的指令计数,因为我想处理线程之间的负载平衡。
  • @masab perf 有什么问题?你可以同时监控你的两个线程吗?
  • @qqibrow 如果可能的话,那么任何到 C/C++ 实现的信息(链接等)都会非常有帮助。
【解决方案3】:

您可以使用标准工具访问perf_event - perf(来自 linux-tools)。它可以与程序的所有线程一起使用,并报告摘要配置文件和每线程(每 pid/每 tid)配置文件。

此配置文件不是精确的硬件计数器,而是每 N 个事件采样的结果,其中 N 个被调整为大约 99 Hz(每秒次数)。您也可以尝试-c 2000000 选项以每 200 万次硬件事件获取样本。例如,循环事件(完整列表 - perf list 或尝试perf stat ./program 中列出的一些)

perf record -e cycles -F 99 ./program
perf record -e cycles -c 2000000 ./program

所有线程的摘要。 -n 会显示样本总数

perf report -n

每个 pid(实际上这里使用的是 tid,因此它允许您选择任何线程)。

文本变体将列出所有记录的带有摘要样本计数的线程(使用-c 2000000,您可以将样本计数乘以 200 万来估计线程的硬件事件计数)

perf report -n -s pid | cat

或类似 ncurses 的交互式变体,您可以在其中选择任何线程并查看其自己的配置文件:

perf report -n -s pid

【讨论】:

  • PPS:您可以尝试多次启动 easyperf 监控:创建新线程,然后为该线程启用计数(在新线程或主线程中调用 perf_init 并使用新线程的 tid).. . perf_event_open man7.org/linux/man-pages/man2/perf_event_open.2.html 有 mna,但我不明白如何为调用设置 inherit 标志,侵入 easyperf 并更改此标志的值可能很有用...
  • PS:据我了解,perf stat 具有精确的计数器值无法分隔线程之间的值(perf.wiki.kernel.org/index.php/Tutorial#Counting_with_perf_stat默认情况下,perf stat 计算进程的所有线程和后续子进程和线程。这可以使用 -i 选项进行更改。无法获得每个线程或每个进程的计数细分。") 。它只有--per-core 分隔,用于系统范围的监控-a;或监控单进程-p pid或单线程-t tid
  • masab,你应该知道你不能将 -c 设置为非常低的数字(对于像循环或指令这样的频繁事件少于几百万,对于像 L3 未命中这样的罕见事件则更少)或 -F非常高(超过几千);否则 perf 将限制 dmesg 中消息的频率。
  • 谢谢!我仍然有几个问题: 1. 当我在生成 perf.data 文件后打开它时,使用 perf report -n,我看到很多基于函数调用的行,我无法区分线程。所以我不能说它是否甚至单独监控线程。但是链接perf.wiki.kernel.org/index.php/Tutorial#Open_file_limits 确实说它是在核心粒度上进行的。 2. 我可以在 perf.data 文件的什么位置找到计数器统计信息?例如指令计数、L3 未命中等。
  • masab,是的,只有perf report -n 将汇总来自所有线程的分析数据,只有“-n -s pid”会显示它。尝试运行perf report -n -s pid | cat 这可能会解决出现分段错误的代码路径。教程中提到了--per-core 模式,但此模式仅适用于整个系统的分析,只有在系统没有其他负载并且每个线程都绑定到不同的 cpu 核心时才能为您提供帮助。 2. 不,perf.data 没有计数信息,它只包含样本。您可以使用所需的事件和 -c 5000000 运行多个记录;然后用样本数估计事件。
猜你喜欢
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 1970-01-01
  • 1970-01-01
  • 2017-09-23
  • 1970-01-01
  • 2011-02-28
相关资源
最近更新 更多