引言
Linux性能检测/调优是一个很大的话题,涉及的内容也非常广泛。目前,从硬件层面到系统层面都提供了一系列硬件支持/软件工具给开发者来检测系统性能以针对具体问题进行调优。
本文主要关注其中的利用性能计数器(Performance Counter)进行性能检测的linux工具Perf,介绍了其强大的能力以及部分使用方法。本文主要部分参考了Brendan D. Gregg的博客,在该博客的Perf Examples分栏下有详细的每个Perf的使用方法,可以进一步详细查看。同博客中的叫法相似,这里对Perf利用Perf_Events来指代,避免产生异义。
Perf_Events概述
Perf Event是面向事件的观察工具。简要来说,Perf_Events可以用于解决下面的问题:
- 为什么内核占用这么多CPU时间?具体是哪一个代码段耗时?
- 哪部分代码导致CPU会导致L2的缓存失效?
- 是否CPU被memory I/O所害?
- 哪段代码在疯狂分配内存?
- 到底谁导致了TCP的重传?
- 是否内核中的某一个方法被调用了,有多频繁?
一共有两种Perf_Events:第一种是直接利用现有提供的Events,其覆盖了大部分可能会用到的事件。而如果刚好里面没有想要的,则需要利用第二种方式,自己写新的Perf_Events。
而针对如何如何利用Perf_Events进行测量,一共有三种方法:
- 直接利用Counting Event计数,可以利用perf工具直接对发生的次数进行计数。这种方法不会生成
perf.data
文件,直接利用perf stat
命令即可。 - 在指定的时间进行取样,使用这种方法会将Perf_Events数据写到内核缓存里面,然后再由Perf隔一段时间写入
perf.data
文件中。最后利用perf report
或者perf script
读取。但是利用这种方法进行采样,report文件的大小overhead比较高(文件很大)。 - 最后一种方法是利用BPF触发用户自己写的程序,这种方法最灵活。但是同时这种方法也比较复杂,需要自己写触发程序,在后面的eBPF章节中进行描述。
Perf_Event的种类与使用方法
如上图所示,Linux Perf_Events可以分为以下几类:
- 硬件事件 Hardware Events: CPU 性能检测计数器
- 软件事件 Software Events: 利用kernel counters低层次的events,例如CPU迁移, minor faults, major faults.
- 内核追踪事件 Kernel Tracepoint Events: 有些内核态的tracepoint被硬件编码到内核中的一些地方。
- 用户态静态追踪事件 User Statically-Defined Tracing (USDT): 用户态程序中的静态tracepoint。
- 动态追踪 Dynamic Tracing: 利用kprobe和uprobe在任意位置创建event。
- Timed Profiling: 可以间隔一段时间时间进行快照。
目前perf支持的事件可以用perf list
列举出来。而如果使用动态追踪,可以追踪其他的事件。下面针对上面几种事件进行详细分析。
硬件事件 Hardware Events
什么是Hardware Events
硬件事件是利用处理器的performance Monitoring Unit(PMU)实现。读取其中的Performace Monitoring Counters(PMCs)或者称为Performance instrumentation counters(PICs)。这些Counter可以跟踪一些底层的动作,如CPU cycles,instructions retired, memory stall cycles, level 2 cache misses等等。
这些硬件事件的特点是只有其中少数几个事件可以同时被记录。 这时因为硬件资源有限,需要手动指定它们记录哪些event。
如何使用Hardware Events
使用硬件Raw Counter的格式是rUUEE
,其中UU
是