perf的使用场景

1、分析CPU cache、CPU迁移,分支预测、指令周期等各种硬件事件。
2、寻找程序运行过程中的热点函数,做性能分析,从而定位性能问题,具体的做法是对事件进行采样,然后再根据采样数,评估调用流程中各个函数的调用频率。
3、自定义追踪感兴趣的事件。

perf list

列出所有能够出发Perf采样点的事件,类似于ftrace中/sys/kernel/debug/tracing/available_events中包含的事件,但Perf支持的事件比ftrace要多。

perf trace

类似于strace跟踪进程系统调用,相较于strace有更好的性能。

$ perf strace ls? (         ): ls/7996  ... [continued]: execve())                                           = 00.078 ( 0.004 ms): ls/7996 brk()                                                                 = 0x556e616e70000.090 ( 0.003 ms): ls/7996 arch_prctl(option: 0x3001, arg2: 0x7ffd2d59b9f0)                      = -1 EINVAL (Invalid argument)0.130 ( 0.012 ms): ls/7996 access(filename: 0x4895c9e0, mode: R)                                 = -1 ENOENT (No such file or directory)0.154 ( 0.010 ms): ls/7996 openat(dfd: CWD, filename: 0x48959b80, flags: RDONLY|CLOEXEC)         = 3
kernel-hook-framework_4.x  text_poke  yin0.168 ( 0.005 ms): ls/7996 fstat(fd: 3, statbuf: 0x7ffd2d59abf0)                                 = 00.177 ( 0.010 ms): ls/7996 mmap(len: 75723, prot: READ, flags: PRIVATE, fd: 3)                   = 0x7fae489210000.190 ( 0.003 ms): ls/7996 close(fd: 3)                                                          = 00.209 ( 0.007 ms): ls/7996 openat(dfd: CWD, filename: 0x48963e10, flags: RDONLY|CLOEXEC)         = 30.221 ( 0.006 ms): ls/7996 read(fd: 3, buf: 0x7ffd2d59ad98, count: 832)                          = 8320.231 ( 0.003 ms): ls/7996 fstat(fd: 3, statbuf: 0x7ffd2d59ac40)                                 = 0
....

perf start

运行命令并收集性能统计信息。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(void)
{printf("hello, pid=%d\n", getpid());while(1) {printf("begin sleep...\n");sleep(1);}
}
// gcc main.c -o main
$ perf stat ./main
hello, pid=8119
begin sleep...
begin sleep...
begin sleep...
^C./main: InterruptPerformance counter stats for './main':0.84 msec task-clock                #    0.000 CPUs utilized          3      context-switches          #    3.576 K/sec                  1      cpu-migrations            #    1.192 K/sec                  54      page-faults               #   64.373 K/sec                  1,364,290      cycles                    #    1.626 GHz                    848,212      instructions              #    0.62  insn per cycle         172,372      branches                  #  205.482 M/sec                  8,017      branch-misses             #    4.65% of all branches        3.000841844 seconds time elapsed0.001547000 seconds user0.000000000 seconds sys# task-clock:用于执行程序的cpu时间;
# context-switches:程序在运行过程中经历的上下文切换次数;
# page-faults:进程运行过程中产生的缺页次数;
# cpu-migrations:程序在运行过程中发生的CPU迁移次数,即被调度器从一个CPU转移到另外一个CPU上运行;
# instructions:该进程在这段时间内完成的CPU指令数;
# cycles:CPU时钟周期;

perf record

运行命令并将产生的数据写入perf.data文件。

# -p $pid 记录进程pid的events
# -a 采集所有cpu上的events
# -e $event 指定PMU(处理器监控单元)event,默认是cycles:app(cpu周期数)
# -g 启动堆栈/栈回溯功能
# -F $freq  采用频率
# -o $path 指定采样文件输出路径
#include <iostream>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>using namespace std;void for_loop()
{for (int i = 0; i < 1000; i++) {for (int j = 0; j < 10000; j++) {int x = sin(i) + cos(j);}}
}void loop_small()
{for (int i = 0; i < 10; i++) {for_loop();}
}void loop_big()
{for (int i = 0; i < 100; i++) {for_loop();}
}int main(void)
{printf("pid=%d\n", getpid());loop_big();loop_small();return 0;}// g++ test.c -p test
# 使用示例
# 采样时间10,采样频率99,可以采集到约1000个事件
$ perf record -p 10086 -a -g -F 100 --sleep 10
$ perf record -p 10086 -a -g -F 1000 --sleep 10
$ perf record -g -e cpu-clock ./test

perf report

对perf record采样的数据进行分析,可视化显示。

--no-childern:不统计chiledren开销Self:Self记录的是最后一列符号(可以理解为函数)本身采样数占总采样数的百分比,从而找到热点函数Children:记录的是这个符号调用的其他符号(理解为子函数,包括间接调用和直接调用)的采样数之和占总采样数的百分比,从而找到较高层热点函数

perf script

从perf.data读取数据并显示详细的采样信息,一般有多少个时间,就有多少条记录。

perf kmem

跟踪/测量内核内存属性

  • record:记录kmem events
    –slab:记录slab申请器的events
    –page:记录page申请器的events
  • stat:报告内核内存统计信息
    –slab:记录slab申请器的events
    –page:记录page申请器的events

perf mem

分析内存访问

perf lock

分析锁的性能

perf kvm

针对kvm虚拟化分析

perf sched

分析内核调度器性能

# record:采集和记录scheduling events
$ perf sched record --sleep 10
$ pref sched record -p 10086 --sleep 10# script:报告采集到的事件
# latency:报告每个任务的调度延迟和进程的其他调度事件
# timehist:提供调度事件分析报告
时间格式:msec.usecwait timetime between sched-out and next sched-in events for the task;task scheduling delaytime between wakeup and actually running;run timerun time for the task;

perf probe

用于自定义添加函数的probe点,可以用perf list来看支持的tracepoint,自定义添加probe点会自动去找内核符号表中的函数,来判断函数是否存在,如果不存在,在添加probe的时候会报错,在内核符号表中找不到需要添加的符号信息,这种方法相较于Kprobe来说免去了驱动编写的过程,提高了效率。

# 查看所有以及注册的probe函数
$ perf probe --list# 添加自定义probe函数
$ perf probe --add submit_bio# 追踪submit_bio probe事件
# -g表示记录函数的调用栈,sleep标志采样事件
# -g                    enables call-graph recording
# -a, --all-cpus        system-wide collection from all CPUs
# -R, --raw-samples     collect raw sample records from all opened counters
$ perf record -e probe:submit_bio -aR -g sleep 10# 删除自定义的probe点
$ perf probe --del

简单使用 -g 参数存在大量的Unkown函数,从perf record产生的结果来看,这部分对应的地址大部分是非法地址。
perf 支持集中栈回溯和栈追踪的集中方法,可以添加一下几个参数,详细信息看以下帮助信息:

$ perf record -h
--call-graph <record_mode[,record_size]>  //设置栈回溯的方式setup and enables call-graph (stack chain/backtrace):record_mode:    call graph recording mode (fp|dwarf|lbr)record_size:    if record_mode is 'dwarf', max size of stack recording (<bytes>)default: 8192 (bytes)Default: fp

栈回溯支持三种模式,(fp|dwarf|lbr),默认为fp模式,三种模式的说明:

fp

fp 就是 Frame Pointer,即 x86 中的 EBP 寄存器,fp 指向当前栈帧栈底地址,此地址保存着上一栈帧的 EBP 值,具体可参考此文章的介绍,根据 fp 就可以逐级回溯调用栈。然而这一特性是会被优化掉的,而且这还是 GCC 的默认行为,在不手动指定 -fno-omit-frame-pointer 时默认都会进行此优化,此时 EBP 被当作一般的通用寄存器使用,以此为依据进行栈回溯显然是错误的。不过尝试指定 -fno-omit-frame-pointer 后依然没法获取到正确的调用栈,根据 GCC 手册的说明,指定了此选项后也并不保证所有函数调用都会使用 fp…… 看来只有放弃使用 fp 进行回溯了。

dwarf

dwarf 是一种调试文件格式,GCC 编译时附加的 -g 参数生成的就是 dwarf 格式的调试信息,其中包括了栈回溯所需的全部信息,使用 libunwind 即可展开这些信息。dwarf 的进一步介绍可参考 “关于 DWARF”,值得一提的是,GDB 进行栈回溯时使用的正是 dwarf 调试信息。实际测试表明使用 dwarf 可以很好的获取到准确的调用栈。

lbr

最后 perf 还支持通过 lbr 获取调用栈,lbr 即 Last Branch Records,是较新的 Intel CPU 中提供的一组硬件寄存器,其作用是记录之前若干次分支跳转的地址,主要目的就是用来支持 perf 这类性能分析工具,其详细说明可参考 “An introduction to last branch records” & “Advanced usage of last branch records”。此方法是性能与准确性最高的手段,然而它存在一个很大的局限性,由于硬件 Ring Buffer 寄存器的大小是有限的,lbr 能记录的栈深度也是有限的,具体值取决于特定 CPU 实现,一般就是 32 层,若超过此限制会得到错误的调用栈。

perf 常见使用方法相关推荐

  1. git原理及常见使用方法

    Git 原理入门-来自阮一峰 Git 是最流行的版本管理工具,也是程序员的必备技能之一. 即使天天使用它,很多人也未必了解它的原理.Git 为什么可以管理版本?git add.git commit这些 ...

  2. ueditor上传图片回调_(常见解决方法)UEditor报错“后端配置项没有正常加载,上传插件不能正常使用”...

    (常见解决方法)UEditor报错"后端配置项没有正常加载,上传插件不能正常使用"_向来萧瑟也无畏-CSDN博客​blog.csdn.net 报错信息 详见此文的"排错过 ...

  3. 学JS的心路历程 -数组常见处理方法

    昨天我们有提到说for-of和forEach可以用来处理数组,但其实还有很多方法可以更快速及精简代码的达到你要的效果. 话不多说,我们赶紧来看吧! Array.prototype.map() 会回传一 ...

  4. Android开发环境搭建及常见问题解决方法

    Android开发环境搭建及常见问题解决方法 参考文章: (1)Android开发环境搭建及常见问题解决方法 (2)https://www.cnblogs.com/rwxwsblog/p/476978 ...

  5. python装饰器函数-Python函数装饰器常见使用方法实例详解

    本文实例讲述了Python函数装饰器常见使用方法.分享给大家供大家参考,具体如下: 一.装饰器 首先,我们要了解到什么是开放封闭式原则? 软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所 ...

  6. 100m和1000m网线的常见制作方法

    100m和1000m网线的常见制作方法 100m和1000m网线的常见制作方法: 5类线(100m)的制作: a: 绿白(3).绿(6).橙白(1).蓝(4).蓝白(5).橙(2).棕白(7).棕(8 ...

  7. PHP几种常见魔术方法与魔术变量解析

    PHP几种常见魔术方法与魔术变量解析 先不多说,直接上代码,如下: 1 class Demo 2 { 3 private $str = 'str'; 4 5 //实例化时自动加载function 6 ...

  8. DL框架之MXNet :神经网络算法简介之MXNet 常见使用方法总结(神经网络DNN、CNN、RNN算法)之详细攻略(个人使用)

    DL框架之MXNet :神经网络算法简介之MXNet 常见使用方法总结(神经网络DNN.CNN.RNN算法)之详细攻略(个人使用) 相关文章 DL框架之MXNet :深度学习框架之MXNet 的简介. ...

  9. DKhadoop安装配置教程与常见问题解决方法

    上周分别就DKHadoop的安装准备工作以及服务器操作系统配置写了两篇分享的文章,这是个人第一次尝试写一个系统性的分享文章,必然会有很多疏漏的地方,还望见谅吧.今天分享的是DKHadoop安装以及常见 ...

最新文章

  1. dhcp报文_动态地址分配DHCP,IP地址管理方式及分配原则,一分钟了解下
  2. 通过Python的__slots__节省9GB内存
  3. post基础-百度翻译接口测试
  4. css button 四种状态,css中按钮的四种状态
  5. elasticsearch删除索引_一文带您了解 Elasticsearch 中,如何进行索引管理(图文教程)
  6. linux db2表空间目录,db2 表空间的一些知识
  7. 前端系统化学习【JS篇】:(二)Javascript、变量和值的简述
  8. android Tabhost 组件
  9. 试题4 基础练习 闰年判断
  10. C#操作mongodb的一些总结
  11. Windows中字体库的安装方法
  12. android 反编译去会员,反编译教程
  13. 移动广告平台Android SDK接入指南
  14. Euclid最大公因数算法及其扩展求逆元
  15. 接口测试用例设计:常见问题和风险
  16. 程序人生 - 如何绘制二维码?
  17. ASAM XCP及驱动代码、ISO 11898+CANFD,ISO 14229,ISO 15031,ISO 15765相关标准文档
  18. 怎样做一次好的活动策划?
  19. Stratifyd入驻腾讯云市场,AI赋能品牌数字化升级
  20. 【python】opencv教程CV2模块——图片处理,HSV、色调、亮度调节

热门文章

  1. 新技术加速隐私暴露,我们该怎么办?(三)
  2. SparkTune: tuning Spark SQL through query cost modeling
  3. js享元模式设计原理以及应用案例
  4. SAP CO系统配置-产品成本控制
  5. 【sql】case when用法
  6. Ribbon负载均衡原理
  7. acme.sh申请域名证书方法记录
  8. 精细化耕耘是B2C转战B2B良好的开端
  9. VM ware虚拟机、Ubuntu系统、Ros安装教程
  10. 前端面试题 ---- html篇