一、引言 (Introduction)
简要介绍Linux perf (Brief Introduction to Linux perf)
Linux perf(性能分析工具)是一个功能强大且灵活的性能剩余工具,它可以在Linux系统上检测和调试各种性能问题。Linux内核集成了perf工具,可用于探测内核性能事件、硬件性能计数器以及用户级应用程序性能事件。
perf工具可以用于剖析(profile)应用程序,从而找出瓶颈和优化点,以提高系统的性能和稳定性。它支持多种统计和视图模式,能够为开发人员和系统管理员提供深入的性能分析。
为什么了解perf对Linux用户至关重要 (Why Understanding perf is Crucial for Linux Users)
了解并掌握perf工具对Linux用户来说至关重要,原因有以下几点:
a) 性能优化:perf可以帮助开发者发现程序中的性能瓶颈,并对其进行优化。通过对代码的性能分析,开发者能够更有效地找出影响性能的关键部分,从而改进程序。
b) 系统监控:系统管理员可以使用perf实时监控Linux系统的资源使用情况,从而及时发现并处理潜在问题,确保系统稳定高效运行。
c) 问题定位:在面对复杂的性能问题时,perf能够提供详细的分析数据,帮助开发者和系统管理员精确定位问题根源,提高解决问题的效率。
d) 学习与理解:perf不仅仅是一个性能分析工具,还能帮助用户更深入地了解Linux系统的运行原理。通过使用perf,用户可以更好地理解Linux内核的工作机制,从而在开发和维护过程中做出更明智的决策。
总之,熟练掌握Linux perf工具可以帮助开发者和系统管理员提高系统性能、解决问题和优化系统资源。从而使得Linux系统运行更加稳定、高效,满足用户需求。
二、perf工具概览 (Overview of perf Tool)
perf工具的来源与发展 (Origin and Development of perf Tool)
perf工具最早源于Linux内核开发者对性能分析需求的不断增长。2009年,Ingo Molnar率先引入了perf工具,并将其合并进Linux内核版本2.6.31。随着时间的推移,perf工具得到了持续改进和发展,成为了Linux内核开发者和系统管理员日常工具的重要组成部分。
perf工具在Linux内核社区的支持下,不断地扩展了其功能和性能分析领域。与此同时,硬件制造商也开始支持perf工具,为各种处理器和平台提供特定的性能计数器。如今,perf工具已经成为Linux内核中一款功能强大且广泛应用的性能分析工具。
perf工具的核心组件 (Core Components of perf Tool)
perf工具主要包括以下几个核心组件:
a) perf事件:perf事件是perf工具的基础,代表了一个特定的性能度量。事件可以是内核、硬件或用户级应用程序产生的。这些事件可以用于监控、统计和剖析各种性能指标。
b) perf计数器:计数器是用于记录perf事件发生次数的设备。内核与硬件之间的接口由内核提供,以便于硬件计数器和perf工具之间的通信。
c) perf命令行工具:perf命令行工具是用户与perf工具进行交互的主要方式。它提供了一系列子命令,如stat、record、report等,用于控制和分析性能数据。
d) perf数据存储:perf工具会将收集到的性能数据存储在特定格式的文件中,以便后续进行分> > 析。用户可以使用perf report命令读取这些文件,并以多种方式展示性能数据。
e) perf分析器:分析器是perf工具的核心组件之一,负责对收集到的性能数据进行深入分析。它能够生成详细的报告,揭示系统和应用程序中的性能瓶颈和优化点。
通过这些核心组件,perf工具为Linux用户提供了强大而灵活的性能分析功能,帮助用户优化系统性能、解决问题和了解Linux系统运行原理。
三、perf的基本命令与用法 (Basic Commands and Usage of perf)
perf list:查看可用事件 (perf list: Viewing Available Events)
使用 perf list
命令可以查看系统中可用的perf事件列表。这些事件包括硬件事件、软件事件和内核跟踪点等。通过这些事件,用户可以选择要监控的性能指标。
$ perf list
以下是 perf list
可用的参数:
-F
或--fields
:指定用于描述事件的输出字段。可以选择多个字段,使用逗号分隔。例如,-F event,desc
将输出事件名称和描述。-H
或--show-hierarchy
:以层次结构形式展示事件列表。--help
:显示帮助信息,包括可用参数和简要说明。--filter
:将事件列表过滤为与指定字符串匹配的事件。
perf stat:查看性能统计信息 (perf stat: Viewing Performance Statistics)
perf stat
命令用于收集和显示性能计数器统计信息。它可以针对整个系统或特定进程收集数据,并显示事件的发生次数、占比等信息。
$ perf stat [options] [command]
以下是 perf stat
的一些常用参数:
-e
或--event
:指定要收集的事件类型,例如:cache-misses, instructions 等。-p
或--pid
:指定要监视的进程ID。-t
或--tid
:指定要监视的线程ID。-a
或--all-cpus
:监视所有CPU,而不仅仅是当前CPU。-C
或--cpu
:指定要监视的CPU列表。-c
或--count
:设置每个事件的采样周期。-r
或--repeat
:重复运行给定的命令并收集统计信息,指定重复次数。-d
或--detailed
:显示详细的统计信息。-D
或--delay
:设置统计输出之间的延迟时间(以毫秒为单位)。-n
或--null
:仅运行命令,不收集统计信息。-o
或--output
:指定将数据写入的文件。-A
或--no-aggr
:不进行聚合统计,为每个硬件事件单独显示结果。--metric-only
:仅显示指定的度量结果,不显示原始硬件事件。--metricgroup
:选择度量组。例如,--metricgroup core
。--metrics
:显示与指定事件相关的度量。--per-socket
:按每个 CPU 套接字显示聚合统计。--per-core
:按每个物理 CPU 核心显示聚合统计。--per-thread
:按每个线程显示聚合统计。--no-merge
:不合并不同 PMU (Performance Monitoring Unit) 的结果。
perf record:记录性能数据 (perf record: Recording Performance Data)
perf record
命令用于收集指定事件的性能数据,并将其保存在文件中以便后续分析。默认情况下,数据将保存在名为 perf.data
的文件中。
$ perf record [options] [command]
以下是perf record
命令的一些常用参数:
-e
或--event
:指定要记录的事件类型,例如cache-misses, instructions等。-p
或--pid
:指定要监控的进程ID。-t
或--tid
:指定要监控的线程ID。-a
或--all-cpus
:监控所有CPU,而不仅仅是当前CPU。-C
或--cpu
:指定要监控的CPU列表。-f
或--overwrite
:以覆盖模式记录事件。-c
或--count
:设置每个事件的采样周期。-r
或--real-time
:设置实时优先级。-o
或--output
:指定要将数据写入的文件。-g
或--call-graph
:指定调用图记录方法,例如dwarf或fp(帧指针)。--switch-events
:记录上下文切换事件。--no-buffering
:禁用数据缓冲。--dry-run
:显示要执行的操作,但不实际执行。
perf report:生成性能报告 (perf report: Generating Performance Reports)
perf report
命令从 perf.data
文件中读取性能数据,并以多种格式展示分析结果。用户可以根据需要自定义报告的输出格式。
$ perf report [options]
以下是 perf report
的一些常用参数:
-i
或--input
:指定要读取的输入文件,默认为perf.data
。-F
或--fields
:指定要显示的字段,例如:comm, dso, symbol 等。--sort
:指定排序顺序,例如:dso,symbol 或 symbol,dso。--show-total-period
:显示每个符号的总周期数。-T
或--threads
:显示线程相关数据。-m
或--modules
:显示模块(共享库)相关数据。-k
或--vmlinux
:指定内核符号表文件(vmlinux)的路径。-f
或--force
:强制解析文件,即使它看起来无效或损坏。-c
或--comms
:指定要显示的命令(进程)列表。--dsos
:指定要显示的动态共享对象(DSO)列表。-s
或--symbols
:指定要显示的符号(函数)列表。--percent-limit
:仅显示超过指定百分比的项。-P
或--pretty
:指定输出格式,如raw、normal等。--stdio
:以文本模式显示报告(而非 TUI 模式)。--tui
:以 TUI 模式显示报告(默认方式)。--gtk
:以 GTK 模式显示报告。-g
或--call-graph
:显示调用图数据。--no-children
:仅显示独立样本,不显示调用子函数的样本。--no-demangle
:禁用 C++ 符号解析。--demangle
:指定 C++ 符号解析方式,如:no, normal, smart 等。--filter
:指定过滤器,如:--filter 'dso(/lib*)'
。--max-stack
:指定栈帧的最大数量。
perf annotate:源码级别的性能分析 (perf annotate: Source Code-Level Performance Analysis)
perf annotate
命令可以实现源码级别的性能分析。它展示了各个函数中指令的性能数据,帮助用户发现程序中的瓶颈。
$ perf annotate [options] [symbol]
以下是 perf annotate
的一些常用参数:
-i
或--input
:指定要读取的输入文件,默认为perf.data
。-s
或--symbol
:指定要注解的符号(函数)名称。-d
或--dsos
:指定要注解的动态共享对象(DSO)名称。-P
或--pretty
:指定输出格式,如raw、normal等。--stdio
:以文本模式显示注解(而非 TUI 模式)。--tui
:以 TUI 模式显示注解(默认方式)。--gtk
:以 GTK 模式显示注解。--no-source
:仅显示汇编代码,不显示源代码。--group
:将指定事件作为事件组进行注解。-f
或--force
:强制解析文件,即使它看起来无效或损坏。--show-total-period
:显示每个符号的总周期数。-k
或--vmlinux
:指定内核符号表文件(vmlinux)的路径。--buildid-dir
:指定包含构建 ID 数据的目录。--buildid-cache-dir
:指定用于缓存构建 ID 数据的目录。--no-cache
:禁用构建 ID 缓存。--percent-type
:指定百分比类型,如:local, global等。--percent-limit
:仅显示超过指定百分比的项。
perf top:实时查看热点函数 (perf top: Real-Time Viewing of Hot Functions)
perf top
命令实时显示系统中最耗费CPU资源的函数。这有助于用户快速定位导致性能问题的代码部分。
$ perf top [options]
以下是 perf top
的一些常用参数:
-e
或--event
:指定要收集的事件类型,例如:cache-misses, instructions 等。-p
或--pid
:指定要监视的进程ID。-t
或--tid
:指定要监视的线程ID。-a
或--all-cpus
:监视所有CPU,而不仅仅是当前CPU。-C
或--cpu
:指定要监视的CPU列表。-d
或--delay
:设置刷新间隔(以毫秒为单位)。-c
或--count
:设置每个事件的采样周期。--call-graph
:设置调用图记录方法,例如:dwarf 或 fp(帧指针)。--real-time
:以实时优先级运行perf top
。-S
或--sort
:指定排序顺序,例如:comm,dso 或 dso,comm。-M
或--show-mmap-events
:显示 mmap 事件。-K
或--hide_kernel_symbols
:隐藏内核符号。-U
或--hide_user_symbols
:隐藏用户空间符号。-z
或--zero
:启动时将计数器清零。--sym-annotate
:运行 perf annotate。--symbols
:指定要显示的符号(函数)列表。--dsos
:指定要显示的动态共享对象(DSO)列表。
perf bench:内置基准测试 (perf bench: Built-In Benchmark Testing)
perf bench
命令提供了一组内置的基准测试,用于评估系统的性能。这些测试涵盖了内存、调度、文件系统等多个方面。
$ perf bench [options] [subcommand]
以下是 perf bench
的一些常用参数:
--list
:列出所有可用的基准测试。--help
:显示帮助信息,包括可用参数和简要说明。-p
或--process
:使用进程实现多任务测试,而非线程(适用于某些基准测试,如sched
)。
perf bench
命令下有几个子命令,可以用于运行不同类型的基准测试:
futex
:针对 futex(快速用户空间互斥锁)操作的基准测试。sched
:针对调度器(进程/线程切换)的基准测试。mem
:针对内存操作的基准测试。kallsyms
:针对内核符号查找的基准测试。cgroup
:针对 cgroup 的基准测试。
perf trace:系统调用跟踪与分析 (perf trace: System Call Tracing and Analysis)
perf trace
命令用于跟踪和分析系统调用,帮助用户了解程序在运行时如何与内核进行交互。这对于排查性能问题和理解系统行为非常有用。
$ perf trace [options] [command]
以下是 perf trace
的一些常用参数:
-a
或--all-cpus
:在所有CPU上监视事件,而不仅仅是在当前CPU上。-C
或--cpu
:指定要监视的CPU列表。-p
或--pid
:指定要监视的进程ID。-t
或--tid
:指定要监视的线程ID。-e
或--event
:指定要监视的事件类型。如:sched, raw_syscalls 等。-i
或--input
:从指定文件读取数据,默认为perf.data
。-o
或--output
:将数据写入指定文件。--duration
:设置监视事件的最长持续时间(以秒为单位)。-g
或--call-graph
:记录调用图信息,例如:dwarf, fp(帧指针)等。-D
或--delay
:设置统计输出之间的延迟时间(以毫秒为单位)。--syscall-events
:仅监视系统调用事件。--tool_stats
:显示工具统计信息。--summary
:显示汇总统计信息。--summary-only
:仅显示汇总统计信息。-s
或--show-syscall-stats
:显示系统调用统计信息。--sched
:显示调度事件。-v
或--verbose
:详细输出。--wide
:宽输出。--no-sys-names
:不显示系统调用名称。--raw-trace
:输出原始跟踪数据,而不是格式化输出。--skip-clear
:在监视之前不清除屏幕。--stats
:显示统计数据。--runtime
:设置最长运行时间(以秒为单位)。--timestamp
:显示时间戳。
以上介绍的是perf工具的一些基本命令和用法,通过这些命令,用户可以针对不同场景进行性能分析.
四、perf实际应用与案例 (Practical Applications and Cases of perf)
CPU性能分析 (CPU Performance Analysis)
perf工具可以分析CPU的使用情况,如缓存命中率、分支预测错误率等。以下是一个使用perf stat
分析CPU性能的简单示例:
$ perf stat -e cycles,instructions,cache-references,cache-misses,branches,branch-misses -- ./my_program
此命令将收集指定事件的数据,并在程序运行结束后显示统计信息。
内存性能分析 (Memory Performance Analysis)
使用perf工具,用户可以对内存访问进行深入分析,以确定内存性能瓶颈。以下示例展示了如何使用perf mem
命令分析内存性能:
$ perf mem record ./my_program $ perf mem report
这将记录内存访问事件并生成报告,帮助用户发现程序中的内存瓶颈。
IO性能分析 (IO Performance Analysis)
perf可以跟踪与IO相关的事件,如磁盘读写操作。以下示例展示了如何使用perf trace
命令分析IO性能:
$ perf trace -e block:block_rq_issue,block:block_rq_complete -- ./my_program
这将跟踪磁盘请求的发出和完成事件,并展示相关信息。
软件性能调优 (Software Performance Tuning)
perf工具可以帮助开发者发现代码中的性能瓶颈,从而进行优化。例如,可以使用perf record
和perf report
命令对程序进行剖析:
$ perf record -g ./my_program $ perf report
这将记录程序的性能数据,并生成一个包含热点函数和调用图的报告。
系统瓶颈定位 (System Bottleneck Localization)
perf可以辅助系统管理员找出系统资源瓶颈,例如使用perf top
命令实时监控耗费CPU资源的函数:
$ perf top
这有助于快速发现系统中的性能问题,并采取相应措施进行优化。
硬件性能评估 (Hardware Performance Evaluation)
perf工具还可以用于评估硬件性能,如处理器、内存等。使用perf bench
命令进行内置基准测试,例如测试内存带宽:
$ perf bench mem memcpy
此命令将执行内存拷贝基准测试,并输出性能数据。
通过这些实际应用和案例,perf工具为开发者、系统管理员和硬件工程师提供了强大的性能分析能力,帮助他们优化软件和硬件,提升整体系统性能。
五、perf生成火焰图
生成火焰图步骤
1. 运行perf
在终端中输入以下命令:
sudo perf record -F 99 -p -g -- sleep 30
perf record表示采集系统事件,
- -F 指定采样频率为 99Hz(每秒99次),如果 99次 都返回同一个函数名, 那就说明 CPU 这一秒钟都在执行同一个函数, 可能存在性能问题.
- -p 表示要分析的进程ID,-g表示采集调用栈信息,-- sleep 30表示运行perf采样30秒。
- -p 2347 是进程号, 即对哪个进程进行分析
- -g 表示记录调用栈, sleep 30 则是持续 30 秒.
- -e :指定要监控的硬件事件,如 CPU 循环计数器、缓存事件等。没有使用 -e 指定采集事件, 则默认采集 cycles(即 CPU clock 周期),
- -a:监控所有进程而不仅仅是指定的进程。
- -t :监控指定线程的事件。
- -o :将记录的数据写入指定的文件中。
- –call-graph :指定要记录的调用图类型,如函数调用图、分支跳转图等。
- –no-samples:只记录事件,不记录采样数据。
- –no-buildid-cache:不使用缓存的 build ID 信息。
- –no-unwind:不进行栈回溯操作,加快采样速度。
- –no-vmlinux:不使用 vmlinux 文件进行符号解析,只使用内核模块的符号表。
- –no-dump:不将采样数据转储到文件中,只输出分析结果。
- –mmap-pages :指定用于存储采样数据的内存页数。
- –max-stack :指定栈回溯的最大深度。
- –time :指定记录的时间长度。
- –weight :为指定事件设置权重,用于平衡多个事件的采样率。
生成火焰图
FlameGraph tool install
$ git clone https://github.com/brendangregg/FlameGraph
Output perf.data/out.perf
perf record -p {pid} -a -g -F 99 -- sleep 10 //生成perf.data perf script > out.perf //通过perf.data 生成out.perf
拷贝out.perf到ubuntu
# 折叠调用栈 FlameGraph/stackcollapse-perf.pl out.perf > out.folded # 生成火焰图 FlameGraph/flamegraph.pl out.folded > out.svg # sudo perf script | stackcollapse-perf.pl | flamegraph.pl > perf.svg
其中,stackcollapse-perf.pl和flamegraph.pl是两个Perl脚本,用于将perf采集到的数据转换成火焰图的格式。perf.svg是生成的火焰图文件名。
查看火焰图
打开perf.svg文件,可以看到生成的火焰图。火焰图的横轴表示时间,纵轴表示调用栈,每个矩形代表一个函数调用,矩形的宽度表示该函数调用的时间占总时间的比例,颜色越深表示该函数调用的嵌套层数越深。
通过观察火焰图,可以找出应用程序的性能瓶颈,进而优化代码。
六、perf的高级技巧与实践 (Advanced Techniques and Practices of perf)
自定义性能事件 (Customizing Performance Events)
perf允许用户自定义事件,以满足特定性能分析需求。例如,通过指定原始事件代码,用户可以定制硬件性能计数器事件:
$ perf stat -e rNNN -- ./my_program
其中NNN
是原始事件代码。此外,还可以使用事件组合来关注多个相关事件:
shellCopy code
$ perf stat -e '{cycles,instructions},{cache-references,cache-misses}' -- ./my_program
结合其他性能工具使用perf (Using perf in Combination with Other Performance Tools)
perf工具可以与其他性能分析工具结合使用,以提供更丰富的性能洞察。例如,使用perf
与FlameGraph
可以生成交互式火焰图,以便更直观地查看性能数据:
$ perf record -g -- ./my_program $ perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > flamegraph.svg
多核性能分析 (Multi-Core Performance Analysis)
在多核处理器系统中,可以使用perf分析各个核心的性能。以下示例展示了如何使用perf stat
命令监控特定CPU核心上的事件:
$ perf stat -C 0-3 -e cycles,instructions -- ./my_program
这将仅监控CPU核心0到3上的事件。
长时间监控与分析 (Long-Term Monitoring and Analysis)
perf可以用于长时间的系统性能监控。例如,可以使用perf record
持续记录性能数据,并在需要时使用perf report
进行分析:
$ perf record -a -F 100 -g -- sleep 86400
这将以100Hz的采样率记录全系统性能数据,持续86400秒(一天)。
分析虚拟化和容器环境中的性能 (Analyzing Performance in Virtualization and Container Environments)
在虚拟化和容器环境中,perf仍然可以提供准确的性能分析。例如,在Docker容器中使用perf工具:
$ docker run --privileged -v /usr/bin/perf:/usr/bin/perf -it my_image /bin/bash
这将在容器内运行perf,允许访问主机的性能计数器。
通过这些高级技巧与实践,perf工具的性能分析能力得到了进一步拓展,使用户能够更深入地挖掘系统性能,从而优化和调试复杂的应用程序和系统环境。
七、常见问题与解决方案 (Common Problems and Solutions of perf)
安装与配置问题 (Installation and Configuration Issues)
问题:在某些发行版中,perf工具可能未被预装或安装不完整。
解决方案:根据您的Linux发行版,使用相应的包管理器安装perf工具包。例如,在基于Debian的系统中,使用以下命令安装:
#linux内核系统 sudo apt-get install linux-tools-common linux-tools-$(uname -r) #wsl:由于 WSL 不是真正的 Linux 内核,因此无法使用 uname -r 命令获取内核版本。 sudo apt-get update sudo apt-get install linux-tools-common linux-tools-generic
数据采集和分析问题 (Data Collection and Analysis Issues)
问题:使用perf收集数据时,某些事件无法正常工作,或数据不准确。
解决方案:检查内核是否支持所需事件。请注意,某些事件可能仅在特定的硬件或内核版本中受支持。如果问题仍然存在,尝试使用不同的事件组合或降低采样率。
报告与解读问题 (Report and Interpretation Issues)
问题:使用perf生成的报告难以解读或包含不易理解的符号。
解决方案:确保程序包含调试符号以便perf解析。使用编译器选项(如-g
)包含调试信息,并在生成报告时指定相应的调试符号路径。此外,学习perf报告中的各种输出格式和视图,以便根据需求定制报告。
兼容性与支持问题 (Compatibility and Support Issues)
问题:在虚拟化环境、容器环境或特定硬件平台中,perf工具无法正常工作。
解决方案:检查内核是否支持perf工具及相应的硬件性能计数器。在虚拟化和容器环境中,可能需要特定的配置选项以允许访问主机的性能计数器。对于特定硬件平台,如嵌入式系统或非x86架构,可能需要针对性地编译perf工具或寻求其他解决方案。
这些常见问题与解决方案有助于用户更好地了解和解决在使用perf工具时可能遇到的问题,从而更有效地进行性能分析和优化。
八、总结与展望 (Summary and Outlook)
perf工具的功能与优势 (Summary of Functions and Advantages of perf Tool)
perf工具是Linux下一款强大的性能分析工具,提供了丰富的性能指标和灵活的命令行选项,以满足各种性能调优需求。其优势包括:
- 直接访问硬件性能计数器,提供精确的性能数据;
- 支持多种事件类型,包括硬件、软件和跟踪点事件;
- 提供全面的性能分析功能,如CPU、内存和IO性能分析;
- 支持多核性能分析和虚拟化/容器环境;
- 可与其他性能分析工具结合使用,提供更深入的性能洞察。
其他性能分析工具及使用场景 (Introduction to Other Performance Analysis Tools and Usage Scenarios)
除了perf工具外,还有其他性能分析工具可供选择:
- gprof:GNU编译器集合中的性能分析工具,主要用于分析程序的函数调用关系和执行时间。
- Valgrind:一款内存调试和性能分析工具,可以检测内存泄漏、缓存未命中等问题。
- SystemTap:一款跟踪和分析内核及用户空间程序的工具,通过脚本语言编写性能探针。
- OProfile:一款系统范围的性能分析工具,支持采样分析和基于硬件性能计数器的分析。
根据不同的性能分析需求和场景,可以灵活选择合适的工具。
对perf未来的期许 (Expectations for the Future of perf)
随着硬件和软件的发展,性能分析工具将不断演进以满足新的挑战。对于perf工具,未来的发展方向可能包括:
- 更强大的可视化功能:集成更丰富的图形界面和可视化功能,以提高用户体验和分析效率。
- 扩展到其他平台:进一步支持不同架构的硬件平台,如ARM、RISC-V等,以满足广泛的应用需求。
- 与人工智能结合:应用机器学习和数据挖掘技术,自动发现性能问题并提供优化建议。
- 更好的云原生支持:适应云原生环境,提供针对微服务、容器和Serverless应用的性能分析解决方案。
通过不断创新和发展,perf工具将继续为Linux用户提供高效、准确的性能分析能力。