系统级性能分析工具perf的介绍与使用

更新时间:2023-07-07 22:29:20 阅读: 评论:0

系统级性能分析⼯具perf的介绍与使⽤
测试环境:Ubuntu16.04 + Kernel:4.4.0-31
系统级性能优化通常包括两个阶段:性能剖析(performance profiling)和代码优化。
性能剖析的⽬标是寻找性能瓶颈,查找引发性能问题的原因及热点代码。
代码优化的⽬标是针对具体性能问题⽽优化代码或编译选项,以改善软件性能。
在性能剖析阶段,需要借助于现有的profiling⼯具,如perf等。在代码优化阶段往往需要借助开发者的经验,编写简洁⾼效的代码,甚⾄在汇编级别合理使⽤各种指令,合理安排各种指令的执⾏顺序。
perf是⼀款Linux性能分析⼯具。Linux性能计数器是⼀个新的基于内核的⼦系统,它提供⼀个性能分析框架,⽐如硬件(CPU、PMU(Performance Monitoring Unit))功能和软件(软件计数器、tracepoint)功能。
通过perf,应⽤程序可以利⽤PMU、tracepoint和内核中的计数器来进⾏性能统计。它不但可以分析制定应⽤程序的性能问题(per thread),也可以⽤来分析内核的性能问题,当然也可以同事分析应⽤程序和内核,从⽽全⾯理解应⽤程序中的性能瓶颈。
使⽤perf,可以分析程序运⾏期间发⽣的硬件事件,⽐如instructions retired、processor clock cycles等;也可以分析软件时间,⽐如page fault和进程切换。
perf是⼀款综合性分析⼯具,⼤到系统全局性性能,再⼩到进程线程级别,甚⾄到函数及汇编级别。
perf提供了⼗⼋般武器,可以拿⼤⼑⼤卸⼋块,也可以拿起⼿术⼑细致分析。
1. 背景知识
1.1 tracepoints
tracepoints是散落在内核源码中的⼀些hook,它们可以在特定的代码被执⾏到时触发,这⼀特定可以被各种trace/debug⼯具所使⽤。
perf将tracepoint产⽣的时间记录下来,⽣成报告,通过分析这些报告,条有⼈缘便可以了解程序运⾏期间内核的各种细节,对性能症状做出准确的诊断。
这些tracepint的对应的sysfs节点在/sys/kernel/debug/tracing/events⽬录下。
1.2 硬件特性之cache
内存读写是很快的,但是还是⽆法和处理器指令执⾏速度相⽐。为了从内存中读取指令和数据,处理器需要等待,⽤处理器时间来衡量,这种等待⾮常漫长。cache是⼀种SRAM,读写速度⾮常快,能和处理器相匹配。因此将常⽤的数据保存在cache中,处理器便⽆需等待,从⽽提⾼性能。cache的尺⼨⼀般都很⼩,充分利⽤cache是软件调优⾮常重要部分。
2. 主要关注点
基于性能分析,可以进⾏算法优化(空间复杂度和时间复杂度权衡)、代码优化(提⾼执⾏速度、减少内存占⽤)。
评估程序对硬件资源的使⽤情况,例如各级cache的访问次数、各级cache的丢失次数、流⽔线停顿周期、前端总线访问次数等。
评估程序对操作系统资源的使⽤情况,系统调⽤次数、上下⽂切换次数、任务迁移次数。
事件可以分为三种:
玫瑰花的习性
1. Hardware Event由PMU部件产⽣,在特定的条件下探测性能事件是否发⽣以及发⽣的次数。⽐如cache命中。
2. Software Event是内核产⽣的事件,分布在各个功能模块中,统计和操作系统相关性能事件。⽐如进程切换,tick数等。
3. Tracepoint Event是内核中静态tracepoint所触发的事件,这些tracepoint⽤来判断程序运⾏期间内核的⾏为细节,⽐如slab分配器的分配次数等。
3. perf的使⽤
perf --help之后可以看到perf的⼆级命令。
序号命令作⽤
1annotate解析perf record⽣成的perf.data⽂件,显⽰被注释的代码。
2archive根据数据⽂件记录的build-id,将所有被采样到的elf⽂件打包。利⽤此压缩
包,可以再任何机器上分析数据⽂件中记录的采样数据。
3bench perf中内置的benchmark,⽬前包括两套针对调度器和内存管理⼦系统的
benchmark。
4buildid-
cache 管理perf的buildid缓存,每个elf⽂件都有⼀个独⼀⽆⼆的buildid。buildid被perf⽤来关联性能数据与elf⽂件。
5buildid-list列出数据⽂件中记录的所有buildid。
6diff对⽐两个数据⽂件的差异。能够给出每个符号(函数)在热点分析上的具体差异。
7evlist列出数据⽂件perf.data中所有性能事件。
8inject该⼯具读取perf record⼯具记录的事件流,并将其定向到标准输出。在被分析代码中的任何⼀点,都可以向事件流中注⼊其它事件。
9kmem针对内核内存(slab)⼦系统进⾏追踪测量的⼯具
依恋造句10kvm⽤来追踪测试运⾏在KVM虚拟机上的Guest OS。
11list列出当前系统⽀持的所有性能事件。包括硬件性能事件、软件性能事件以及检查点。
12lock分析内核中的锁信息,包括锁的争⽤情况,等待延迟等。
13mem内存存取情况
14record收集采样信息,并将其记录在数据⽂件中。随后可通过其它⼯具对数据⽂件进⾏分析。
15report读取perf record创建的数据⽂件,并给出热点分析结果。
16sched针对调度器⼦系统的分析⼯具。
17script执⾏perl或python写的功能扩展脚本、⽣成脚本框架、读取数据⽂件中的数据信息等。
18stat执⾏某个命令,收集特定进程的性能概况,包括CPI、Cache丢失率等。19test perf对当前软硬件平台进⾏健全性测试,可⽤此⼯具测试当前的软硬件平台
是否能⽀持perf的所有功能。
20timechart针对测试期间系统⾏为进⾏可视化的⼯具
21top类似于linux的top命令,对系统性能进⾏实时分析。
22trace关于syscall的⼯具。
23probe⽤于定义动态检查点。
全局性概况:
perf list查看当前系统⽀持的性能事件;
perf bench对系统性能进⾏摸底;
perf test对系统进⾏健全性测试;
perf stat对全局性能进⾏统计;
全局细节:
perf top可以实时查看当前系统进程函数占⽤率情况;
perf probe可以⾃定义动态事件;
特定功能分析:
perf kmem针对slab⼦系统性能分析;
perf kvm针对kvm虚拟化分析;
perf lock分析锁性能;
perf mem分析内存slab性能;
perf sched分析内核调度器性能;
perf trace记录系统调⽤轨迹;
最常⽤功能perf record,可以系统全局,也可以具体到某个进程,更甚具体到某⼀进程某⼀事件;可宏观,也可以很微观。
文物建筑pref record记录信息到perf.data;
perf report⽣成报告;
perf diff对两个记录进⾏diff;
perf evlist列出记录的性能事件;
perf annotate显⽰perf.data函数代码;
perf archive将相关符号打包,⽅便在其它机器进⾏分析;
perf script将perf.data输出可读性⽂本;
可视化⼯具perf timechart
perf timechart record记录事件;
perf timechart⽣成output.svg⽂档;
3.0 perf引⼊的overhead
perf测试不可避免的会引⼊额外负荷,有三种形式:
counting:内核提供计数总结,多是Hardware Event、Software Events、PMU计数等。相关命令perf stat。
sampling:perf将事件数据缓存到⼀块buffer中,然后异步写⼊到perf.data⽂件中。使⽤perf report等⼯具进⾏离线分析。
bpf:Kernel 4.4+新增功能,可以提供更多有效filter和输出总结。
counting引⼊的额外负荷最⼩;sampling在某些情况下会引⼊⾮常⼤的负荷;bpf可以有效缩减负荷。
针对sampling,可以通过挂在建⽴在RAM上的⽂件系统来有效降低读写I/O引⼊的负荷。
mkdir /tmpfs
mount -t tmpfs tmpfs /tmpfs
3.1 perf list
perf list不能完全显⽰所有⽀持的事件类型,需要sudo perf list。
同时还可以显⽰特定模块⽀持的perf事件:hw/cache/pmu都是硬件相关的;tracepoint基于内核的ftrace;sw实际上是内核计数器。hw/hardware显⽰⽀持的硬件事件相关,如:
al@al-System-Product-Name:~/perf$ sudo perf list hardware
List of pre-defined events (to be ud in -e):
branch-instructions OR branches                    [Hardware event]
branch-miss                                      [Hardware event]
cache-miss                                      [Hardware event]
cache-references                                  [Hardware event]
cpu-cycles OR cycles                              [Hardware event]
instructions                                      [Hardware event]
stalled-cycles-backend OR idle-cycles-backend      [Hardware event]
stalled-cycles-frontend OR idle-cycles-frontend    [Hardware event]
sw/software显⽰⽀持的软件事件列表:
al@al-System-Product-Name:~/perf$ sudo perf list sw
List of pre-defined events (to be ud in -e):
alignment-faults                                  [Software event]
bpf-output                                        [Software event]
context-switches OR cs                            [Software event]
cpu-clock                                          [Software event]
cpu-migrations OR migrations                      [Software event]
dummy                                              [Software event]
emulation-faults                                  [Software event]
major-faults                                      [Software event]
minor-faults                                      [Software event]
page-faults OR faults                              [Software event]
task-clock                                        [Software event]
三年级语文生字
cache/hwcache显⽰硬件cache相关事件列表:
al@al-System-Product-Name:~/perf$ sudo perf list cache
List of pre-defined events (to be ud in -e):
L1-dcache-load-miss                              [Hardware cache event]
L1-dcache-loads                                    [Hardware cache event]
L1-dcache-prefetch-miss                          [Hardware cache event]
L1-dcache-prefetches                              [Hardware cache event]
L1-icache-load-miss                              [Hardware cache event]
L1-icache-loads                                    [Hardware cache event]
L1-icache-prefetches                              [Hardware cache event]
LLC-load-miss                                    [Hardware cache event]
LLC-loads                                          [Hardware cache event]
LLC-stores                                        [Hardware cache event]
branch-load-miss                                [Hardware cache event]
branch-loads                                      [Hardware cache event]
dTLB-load-miss                                  [Hardware cache event]
dTLB-loads                                        [Hardware cache event]
iTLB-load-miss                                  [Hardware cache event]
iTLB-loads                                        [Hardware cache event]
node-load-miss                                  [Hardware cache event]
node-loads                                        [Hardware cache event]
pmu显⽰⽀持的PMU事件列表:
al@al-System-Product-Name:~/perf$ sudo perf list pmu
List of pre-defined events (to be ud in -e):
branch-instructions OR cpu/branch-instructions/    [Kernel PMU event]
branch-miss OR cpu/branch-miss/                [Kernel PMU event]
cache-miss OR cpu/cache-miss/                  [Kernel PMU event]
cache-references OR cpu/cache-references/          [Kernel PMU event]
cpu-cycles OR cpu/cpu-cycles/                      [Kernel PMU event]
instructions OR cpu/instructions/                  [Kernel PMU event]
msr/aperf/                                        [Kernel PMU event]
msr/mperf/                                        [Kernel PMU event]
msr/tsc/                                          [Kernel PMU event]
stalled-cycles-backend OR cpu/stalled-cycles-backend/ [Kernel PMU event]
stalled-cycles-frontend OR cpu/stalled-cycles-frontend/ [Kernel PMU event]
tracepoint显⽰⽀持的所有tracepoint列表,这个列表就⽐较庞⼤:
al@al-System-Product-Name:~/perf$ sudo perf list tracepoint
List of pre-defined events (to be ud in -e):
alarmtimer:alarmtimer_cancel                      [Tracepoint event]
alarmtimer:alarmtimer_fired                        [Tracepoint event]
alarmtimer:alarmtimer_start                        [Tracepoint event]
alarmtimer:alarmtimer_suspend                      [Tracepoint event]
block:block_bio_backmerge                          [Tracepoint event]
block:block_bio_bounce                            [Tracepoint event]
block:block_bio_complete                          [Tracepoint event]
block:block_bio_frontmerge                        [Tracepoint event]
block:block_bio_queue                              [Tracepoint event]
3.2 perf top
默认情况下perf top是⽆法显⽰信息的,需要sudo perf top或者echo -1 > /proc/sys/kernel/perf_event_paranoid(在Ubuntu16.04,还需要echo 0 > /proc/sys/kernel/kptr_restrict)。即可以正常显⽰perf top如下:
第⼀列:符号引发的性能事件的⽐例,指占⽤的cpu周期⽐例。
第⼆列:符号所在的DSO(Dynamic Shared Object),可以是应⽤程序、内核、动态链接库、模块。
第三列:DSO的类型。[.]表⽰此符号属于⽤户态的ELF⽂件,包括可执⾏⽂件与动态链接库;[k]表述此符号属于内核或模块。
第四列:符号名。有些符号不能解析为函数名,只能⽤地址表⽰。
关于perf top界⾯常⽤命令如下:
h:显⽰帮助,即可显⽰详细的帮助信息。
UP/DOWN/PGUP/PGDN/SPACE:上下和翻页。
a:annotate current symbol,注解当前符号。能够给出汇编语⾔的注解,给出各条指令的采样率。
d:过滤掉所有不属于此DSO的符号。⾮常⽅便查看同⼀类别的符号。
P:将当前信息保存到perf.hist.N中。
perf top常⽤选项有:
-e <event>:指明要分析的性能事件。
-p <pid>:Profile events on existing Process ID (comma sperated list). 仅分析⽬标进程及其创建的线程。
-k <path>:Path to vmlinux. Required for annotation functionality. 带符号表的内核映像所在的路径。
-K:不显⽰属于内核或模块的符号。
-U:不显⽰属于⽤户态程序的符号。
-d <n>:界⾯的刷新周期,默认为2s,因为perf top默认每2s从mmap的内存区域读取⼀次性能数据。
-g:得到函数的调⽤关系图。
perf top --call-graph [fractal],路径概率为相对值,加起来为100%,调⽤顺序为从下往上。
perf top --call-graph graph,路径概率为绝对值,加起来为该函数的热度。
3.3 perf stat
perf stat⽤于运⾏指令,并分析其统计结果。虽然perf top也可以指定pid,但是必须先启动应⽤才能查看信息。
自然爱perf stat能完整统计应⽤整个⽣命周期的信息。
命令格式为:
perf stat [-e <EVENT> | --event=EVENT] [-a] <command>
perf stat [-e <EVENT> | --event=EVENT] [-a] — <command> [<options>]
下⾯简单看⼀下perf stat 的输出:
al@al-System-Product-Name:~/perf$ sudo perf stat
^C
Performance counter stats for 'system wide':
40904.820871      cpu-clock (mc)          #    5.000 CPUs utilized
18,132      context-switches          #    0.443 K/c
1,053      cpu-migrations            #    0.026 K/c
2,420      page-faults              #    0.059 K/c
3,958,376,712      cycles                    #    0.097 GHz                      (49.99%)
574,598,403      stalled-cycles-frontend  #  14.52% frontend cycles idle    (49.98%)
9,392,982,910      stalled-cycles-backend    #  237.29% backend cycles idle      (50.00%)
1,653,185,883      instructions              #    0.42  insn per cycle
#    5.68  stalled cycles per insn  (50.01%)
237,061,366      branches                  #    5.795 M/c                    (50.02%)
18,333,168      branch-miss            #    7.73% of all branches          (50.00%)
8.181521203 conds time elapd
桃花始盛开输出解释如下:
cpu-clock:任务真正占⽤的处理器时间,单位为ms。CPUs utilized = task-clock / time elapd,CPU的占⽤率。
context-switches:程序在运⾏过程中上下⽂的切换次数。
CPU-migrations:程序在运⾏过程中发⽣的处理器迁移次数。Linux为了维持多个处理器的负载均衡,在特定条件下会将某个任务从⼀个CPU迁移到另⼀个CPU。
CPU迁移和上下⽂切换:发⽣上下⽂切换不⼀定会发⽣CPU迁移,⽽发⽣CPU迁移时肯定会发⽣上下⽂切换。发⽣上下⽂切换有可能只是把上下⽂从当前CPU中换出,下⼀次调度器还是将进程安排在这个CPU上执⾏。赋予的拼音
page-faults:缺页异常的次数。当应⽤程序请求的页⾯尚未建⽴、请求的页⾯不在内存中,或者请求的页⾯虽然在内存中,但物理地址和虚拟地址的映射关系尚未建⽴时,都会触发⼀次缺页异常。另外TLB不命中,页⾯访问权限不匹配等情况也会触发缺页异常。
cycles:消耗的处理器周期数。如果把被ls使⽤的cpu cycles看成是⼀个处理器的,那么它的主频为2.486GHz。可以⽤cycles / task-clock算出。
stalled-cycles-frontend:指令读取或解码的质量步骤,未能按理想状态发挥并⾏左右,发⽣停滞的时钟周期。
stalled-cycles-backend:指令执⾏步骤,发⽣停滞的时钟周期。
instructions:执⾏了多少条指令。IPC为平均每个cpu cycle执⾏了多少条指令。
branches:遇到的分⽀指令数。branch-miss是预测错误的分⽀指令数。
其他常⽤参数
-a, --all-cpus        显⽰所有CPU上的统计信息
-C, --cpu <cpu>      显⽰指定CPU的统计信息
-c, --scale          scale/normalize counters
-D, --delay <n>      ms to wait before starting measurement after program start
-d, --detailed        detailed run - start a lot of events
-e, --event <event>  event lector. u 'perf list' to list available events
-G, --cgroup <name>  monitor event in cgroup name only
-g, --group          put the counters into a counter group
-I, --interval-print <n>
print counts at regular interval in ms (>= 10)
-i, --no-inherit      child tasks do not inherit counters
-n, --null            null run - dont start any counters
-o, --output <file>  输出统计信息到⽂件
-p, --pid <pid>      stat events on existing process id
-r, --repeat <n>      repeat command and print average + stddev (max: 100, forever: 0)
-
S, --sync            call sync() before starting a run
-t, --tid <tid>      stat events on existing thread id
...
⽰例
前⾯统计程序的⽰例,下⾯看⼀下统计CPU信息的⽰例:
执⾏sudo perf stat -C 0,统计CPU 0的信息。想要停⽌后,按下Ctrl+C终⽌。可以看到统计项⼀样,只是统计对象变了。
al@al-System-Product-Name:~/perf$ sudo perf stat -C 0
^C
Performance counter stats for 'CPU(s) 0':
2517.107315      cpu-clock (mc)          #    1.000 CPUs utilized
2,941      context-switches          #    0.001 M/c
109      cpu-migrations            #    0.043 K/c
38      page-faults              #    0.015 K/c
644,094,340      cycles                    #    0.256 GHz                      (49.94%)
70,425,076      stalled-cycles-frontend  #  10.93% frontend cycles idle    (49.94%)
965,270,543      stalled-cycles-backend    #  149.86% backend cycles idle      (49.94%)
623,284,864      instructions              #    0.97  insn per cycle
#    1.55  stalled cycles per insn  (50.06%)
65,658,190      branches                  #  26.085 M/c                    (50.06%)
3,276,104      branch-miss            #    4.99% of all branches          (50.06%)
2.516996126 conds time elapd
如果需要统计更多的项,需要使⽤-e,如:
perf stat -e task-clock,context-switches,cpu-migrations,page-faults,cycles,stalled-cycles-frontend,stalled-cycles-backend,instructions,branches,branch-miss,L1-dcache-loads,L1-dcache-load-miss,LLC-loads,LLC-load-miss,dTLB-loads,dTLB-load-miss ls
结果如下,关注的特殊项也纳⼊统计。
al@al-System-Product-Name:~/perf$ sudo perf stat -e task-clock,context-switches,cpu-migrations,page-faults,cycles,stalled-cycles-frontend,stalled-cycles-backend,instructions,branches,branch-miss,L1-dcache-loads,L1-dcache-load-miss,LLC-loads,LLC-load-miss,dTLB-loads,dTLB-load-miss ls
Performance counter stats for 'ls':
2.319422      task-clock (mc)        #    0.719 CPUs utilized
0      context-switches          #    0.000 K/c
0      cpu-migrations            #    0.000 K/c
89      page-faults              #    0.038 M/c
2,142,386      cycles                    #    0.924 GHz
659,800      stalled-cycles-frontend  #  30.80% frontend cycles idle
725,343      stalled-cycles-backend    #  33.86% backend cycles idle
1,344,518      instructions              #    0.63  insn per cycle
#    0.54  stalled cycles per insn
<not counted>      branches
<not counted>      branch-miss
<not counted>      L1-dcache-loads
<not counted>      L1-dcache-load-miss
<not counted>      LLC-loads
<not counted>      LLC-load-miss
<not counted>      dTLB-loads
<not counted>      dTLB-load-miss
0.003227507 conds time elapd
3.4 perf bench
perf bench作为benchmark⼯具的通⽤框架,包含sched/mem/numa/futex等⼦系统,all可以指定所有。
perf bench可⽤于评估系统sched/mem等特定性能。
perf bench sched:调度器和IPC机制。包含messaging和pipe两个功能。
perf bench mem:内存存取性能。包含memcpy和memt两个功能。
perf bench numa:NUMA架构的调度和内存处理性能。包含mem功能。
perf bench futex:futex压⼒测试。包含hash/wake/wake-parallel/requeue/lock-pi功能。
perf bench all:所有bench测试的集合
3.4.1 perf bench sched all
测试messaging和pipi两部分性能。
3.4.1.1 sched messaging评估进程调度和核间通信
sched message 是从经典的测试程序 hackbench 移植⽽来,⽤来衡量调度器的性能,overhead 以及可扩展性。
该 benchmark 启动 N 个 reader/nder 进程或线程对,通过 IPC(socket 或者 pipe) 进⾏并发的读写。⼀般⼈们将 N 不断加⼤来衡量调度器的可扩展性。留的五笔怎么打字
sched message 的⽤法及⽤途和 hackbench ⼀样,可以通过修改参数进⾏不同⽬的测试:
-g, --group <n> Specify number of groups
-l, --nr_loops <n> Specify the number of loops to run (default: 100)
-p, --pipe U pipe() instead of socketpair()
-t, --thread Be multi thread instead of multi process
测试结果:
al@al-System-Product-Name:~/perf$ perf bench sched all
# Running sched/
# 20 nder and receiver process per group
# 10 groups == 400 process run
Total time: 0.173 [c]
# Running sched/
# Executed 1000000 pipe operations between two process
Total time: 12.233 [c]
12.233170 ucs/op
81744 ops/c

本文发布于:2023-07-07 22:29:20,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1072172.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:性能   分析   事件   内核   系统
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图