perf usecase.md - openthos/openthos GitHub Wiki

perf分析的前提

以某应用性能分析为例

观察之前, 应该先回答以下问题:

  1. 你要测的性能指标是什么? (既然是数据库, 那估计是 TPS?)
  2. 该性能指标是怎么计算出来的? 它的基础过程是什么? (一个查询?) 这些过程是并行的还是串行的?
  3. 你做的优化在这个基础过程中处于什么位置? 如果将一个过程分解, 被优化的部分在整体部分中是什么位置? 优化前占整体过程的百分比?
  4. 你预测应用了该优化后该过程的情景变成什么样了? 对1中提到的性能指标能产生什么影响?
  5. 为了观察到你在4中提到的变化, 应该看哪些指标? 或者抓什么 Trace?

使用建议建议:

  1. 按 tracepoint, 抓 sched:sched_switch 和 raw_syscalls, 分析调度轨迹, 看看程序是否串行部分过多, 没有达到题主期望的并行度. 这方面可以借助图形化工具 TraceCompass, 不过用起来确实比较复杂. 基本的顺序是:
# perf record -a -e sched:sched_switch -e raw_syscalls:* --exclude-perf ...
# perf data convert --to-ctf ./out.ctf

将 out.ctf 导入 TraceCompass 工具 也可以在 convert 成 CTF 后借助 libbabeltrace 用 python 脚本分析. 简单的话也可以手工分析.

  1. 如果使用的是 pthread 的 mutex, 也可以观察一下 futex 系统调用的情况. 用 strace 看就可以, 不过用
# perf record -a -e syscalls:sys_enter_futex -e syscalls:sys_exit_futex ...

开销也许会小一些.

  1. 想得到某个用户态函数的执行时间, 可以通过 uprobe 打点:
# perf probe /a/b/c.so func
# perf probe /a/b/c.so func%return

然后抓这两个点, 用 perf script 观察函数进入和退出的时间.

  1. 如果用了用户态自旋锁(如果是题主自己实现的, 恐怕要检查一下自旋锁实现的正确性), 可以用 perf top 观察一下该自旋锁是否为热点函数.

  2. 如果有这种疑问: "可能有个指令执行的次数较多,但不一定耗时啊", 可以关注一下 cycles 和 instructions.

# perf stat -e {cycles,instructions} ...

然后计算一下 IPC, 看看指令执行的快还是慢. 有 TopDown 模型能够将这些计数器翻译成更容易理解的数据. 不过只有 vTune 知道这些细节.

系统级的性能分析可以关注一下 Brendan Gregg 的 blog.