容器中的诊断与分析2——live diagnosis——perf

 

Linux下的内核测试工具——perf使用简介

系统级性能分析工具 — Perf

linux perf - 性能测试和优化工具:示例&应用

 

 从2.6.31内核开始,linux内核自带了一个性能分析工具perf,能够进行函数级与指令级的热点查找。

 介绍:

Perf是内置于Linux内核源码树中的性能剖析(profiling)工具。Linux kernel自带的系统性能优化工具

基于事件采样原理,以性能事件为基础,支持针对处理器相关性能指标操作系统相关性能指标的性能剖析。

常用于性能瓶颈的查找热点代码的定位

优势:

与Linux Kernel的紧密结合,它可以最先应用到加入Kernel的new feature。而像OProfile, GProf等通常会“慢一拍”。

pef可以用于查看热点函数,查看cashe miss的比率,从而帮助开发者来优化程序性能。

运行原理:

  • 性能调优工具如 perf,Oprofile 等的基本原理都是对被监测对象进行采样。是功能级和指令级热外表
    • 在CPU的PMU registers中Get/Set performance counters来获得诸如instructions executed, cache-missed suffered, branches mispredicted等信息。
    • Linux kernel对这些registers进行了一系列抽象,所以你可以按进程,按CPU或者按counter group等不同类别来查看Sample信息。
  • 最简单的情形是根据 tick 中断进行采样,即在 tick 中断内触发采样点,在采样点里判断程序当时的上下文。
    • 假如一个程序 90% 的时间都花费在函数 foo() 上,那么 90% 的采样点都应该落在函数 foo() 的上下文中。
    • 运气不可捉摸,但我想只要采样频率足够高,采样时间足够长,那么以上推论就比较可靠。
    • 因此,通过 tick 触发采样,我们便可以了解程序中哪些地方最耗时间,从而重点分析。
  • 稍微扩展一下思路,就可以发现改变采样的触发条件使得我们可以获得不同的统计数据:
    • 以时间点 ( 如 tick) 作为事件触发采样便可以获知程序运行时间的分布。
    • 以 cache miss 事件触发采样便可以知道 cache miss 的分布,即 cache 失效经常发生在哪些程序代码中。如此等等。
    • 使用perf list(在root权限下运行),可以列出所有的采样事件。事件分为以下三种:
      • Hardware Event 是由 PMU 硬件产生的事件,比如 cache 命中,当您需要了解程序对硬件特性的使用情况时,便需要对这些事件进行采样
      • Software Event 是内核软件产生的事件,比如进程切换,tick 数等 ;
      • Tracepoint event 是内核中的静态 tracepoint 所触发的事件,这些 tracepoint 用来判断程序运行期间内核的行为细节,比如 slab 分配器的分配次数等。
      • 上述每一个事件都可以用于采样,并生成一项统计数据,时至今日,尚没有文档对每一个 event 的含义进行详细解释。

CPU周期(cpu-cycles):

是默认的性能事件,

是指CPU所能识别的最小时间单元,通常为亿分之几秒,

是CPU执行最简单的指令时所需要的时间,例如读取寄存器中的内容,也叫做clock tick。

Perf是一个包含22种子工具的工具集,以下是最常用的5种:

  • perf-list:
    • 用来查看perf所支持的性能事件,有软件的也有硬件的。查看所有可用的counters
    • perf list [hw | sw | cache | tracepoint | event_glob]
      • hw:Hardware event,9个
      • sw:Software event,9个
      • cache:Hardware cache event,26个
      • tracepoint:Tracepoint event,775个
    • sw实际上是内核的计数器,与硬件无关。

    • hw和cache是CPU架构相关的,依赖于具体硬件。

    • tracepoint是基于内核的ftrace,主线2.6.3x以上的内核版本才支持。

      • 什么时候需要使用 tracepoint 来采样呢?
        • 对内核的运行时行为的关心
          • 有些内核开发人员需要专注于特定的子系统,比如内存管理模块。这便需要统计相关内核函数的运行情况。另外,内核行为对应用程序性能的影响也是不容忽视的:
          • 例如,报告详细说明了在 ls 运行期间发生了多少次系统调用 ( 上例中有 101 次 ),多数系统调用都发生在哪些地方 (97% 都发生在 ld-2.12.so 中 )。
  • perf-stat:概览程序的运行情况
    • 分析指定程序的性能概况。面对一个问题程序,最好采用自顶向下的策略。先整体看看该程序运行时各种统计事件的大概,再针对某些方向深入细节。而不要一下子扎进琐碎细节,会一叶障目的
      • 有些程序慢是因为计算量太大,其多数时间都应该在使用CPU进行计算,这叫做CPUbound型;有些程序慢是因为过多的IO,这种时候其CPU利用率应该不高,这叫做IObound型;对于CPUbound程序的调优和IObound的调优是不同的。
      • Perfstat应该是您最先使用的一个工具。它通过概括精简的方式提供被调试程序运行的整体情况和汇总数据。
      • 进行调优应该要找到热点 ( 即最耗时的代码片段 ),再看看是否能够提高热点代码的效率。
    • perf stat [-e <EVENT> | --event=EVENT] [-a] - <command> [<options>]
    • task-clock:任务真正占用的处理器时间,单位为ms。CPUs utilized = task-clock / time elapsed,CPU的占用率。
      • Task-clock-msecs:CPU 利用率,该值高,说明程序的多数时间花费在 CPU 计算上而非 IO。
    • context-switches:上下文的切换次数。
    • Cache-misses:程序运行过程中总体的 cache 利用情况,如果该值过高,说明程序的 cache 利用不好
    • CPU-migrations:处理器迁移次数。Linux为了维持多个处理器的负载均衡,在特定条件下会将某个任务从一个CPU迁移到另一个CPU。

    • page-faults:缺页异常的次数。当应用程序请求的页面尚未建立、请求的页面不在内存中,或者请求的页面虽然在内存中,但物理地址和虚拟地址的映射关系尚未建立时,都会触发一次缺页异常。另外TLB不命中,页面访问权限不匹配等情况也会触发缺页异常。

    • cycles:消耗的处理器周期数。如果把被ls使用的cpu cycles看成是一个处理器的,那么它的主频为2.486GHz。
      • 可以用cycles / task-clock算出。
    • instructions:执行了多少条指令。IPC为平均每个cpu cycle执行了多少条指令。
    • branches:遇到的分支指令数。branch-misses是预测错误的分支指令数。
    • IPC:是 Instructions/Cycles 的比值,该值越大越好,说明程序充分利用了处理器的特性。
    • Cache-references: cache 命中的次数
    • Cache-misses: cache 失效的次数。
  • perf-top:
    • 对于一个指定的性能事件(默认是CPU周期),显示消耗最多的函数或指令
    • perf top [-e <EVENT> | --event=EVENT] [<options>]
    • 要用于实时分析各个函数在某个性能事件上的热度,能够快速的定位热点函数,包括应用程序函数、模块函数与内核函数,甚至能够定位到热点指令。

    • 第一列:符号引发的性能事件的比例,默认指占用的cpu周期比例。

    • 第二列:符号所在的DSO(Dynamic Shared Object),可以是应用程序、内核、动态链接库、模块。

    • 第三列:DSO的类型。[.]表示此符号属于用户态的ELF文件,包括可执行文件与动态链接库)。[k]表述此符号属于内核或模块。

    • 第四列:符号名。有些符号不能解析为函数名,只能用地址表示。

  • perf-record:精确制导——定位程序瓶颈
    • 收集采样信息,并将其记录在数据文件中。
      • 随后可以通过其它工具(perf-report)对数据文件进行分析,结果类似于perf-top的。
    • 查找时间上的热点函数
    • 3个问题
      • perf未能定位本地符号表对应的symbol和地址的对应关系:0x000003d4对应的什么函数?
      • 采样频率不够高,失去了一些函数的信息:显然一些内核函数没有显示在上面的结果中,因为采样频率如果不够高,那么势必会有一些函数中的采样点没有/
        • 用perf record -F count 来指定采样频率
      • 如何克服采样的随机性带来的问题:为了在测量更加逼近正确值,我们采用多次重复取平均值的方法来逼近真实值。(这里可以用-r来指定重复次数)
  • perf-report:精确制导——定位程序瓶颈
    • 读取perf :record创建的数据文件,并给出热点分析结果。
  • perf-lock
    • 内核锁的性能分析。
    • perf lock {record | report | script | info}
    • Name:内核锁的名字。

    • aquired:该锁被直接获得的次数,因为没有其它内核路径占用该锁,此时不用等待。

    • contended:该锁等待后获得的次数,此时被其它内核路径占用,需要等待。

    • total wait:为了获得该锁,总共的等待时间。

    • max wait:为了获得该锁,最大的等待时间。

    • min wait:为了获得该锁,最小的等待时间。
  • perm-kmem
    • slab分配器的性能分析。
    • perf kmem {record | stat} [<options>]
    • Callsite:内核代码中调用kmalloc和kfree的地方。

    • Total_alloc/Per:总共分配的内存大小,平均每次分配的内存大小。

    • Total_req/Per:总共请求的内存大小,平均每次请求的内存大小。

    • Hit:调用的次数。

    • Ping-pong:kmalloc和kfree不被同一个CPU执行时的次数,这会导致cache效率降低。

    • Frag:碎片所占的百分比,碎片 = 分配的内存 - 请求的内存,这部分是浪费的。

    • 有使用--alloc选项,还会看到Alloc Ptr,即所分配内存的地址
  • probe-sched
    • 调度模块分析。 
    • perf sched {record | latency | map | replay | script}
    • TASK:进程名和pid。

    • Runtime:实际的运行时间。

    • Switches:进程切换的次数。

    • Average delay:平均的调度延迟。

    • Maximum delay:最大的调度延迟。

    • Maximum delay at:最大调度延迟发生的时刻。
  • perf-probe
    • 自定义探测点。
  • 还有一些适用于较特殊场景的工具, 比如内核锁、slab分配器、调度器,也支持自定义探测点。

[1]. Linux的系统级性能剖析工具系列,by 承刚

[2]. http://www.ibm.com/developerworks/cn/linux/l-cn-perf1/

[3]. http://www.ibm.com/developerworks/cn/linux/l-cn-perf2/

[4]. https://perf.wiki.kernel.org/index.php/Tutorial

google perftools分析程序性能

介绍

通过采样的方式,给程序中cpu的使用情况进行“画像”

  • 通过它所输出的结果,我们可以对程序中各个函数(得到函数之间的调用关系)耗时情况一目了然
  • 对程序做性能优化的时候,这个是很重要的,先把最耗时的若干个操作优化好,程序的整体性能提升应该十分明显,这也是做性能优化的一个最为基本的原则—先优化最耗时的

下载 gperftools:https://code.google.com/p/gperftools/downloads/detail?name=gperftools-2.0.tar.gz

搭配组件:

安装图形化分析工具kcachegrind:

  • 来分析产生的profiling文件,linux环境下使用。
  • 采用kcachegrind查看函数之间依赖,并分析程序性能

查看profile结果:pprof工具

  • 是一个perl的脚本,通过这个工具,可以将google-perftool的输出结果分析得更为直观,输出为图片、pdf等格式。
  • 在使用pprof之前需要先安装运行per15;如果要进行图标输出则需要安装dot;如果需要--gv模式的输出则需要安装gv

 

sw实际上是内核的计数器,与硬件无关。

原文地址:https://www.cnblogs.com/panpanwelcome/p/10560061.html