嵌入式技术
一、引言 (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
-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用户提供高效、准确的性能分析能力。
编辑:黄飞
全部0条评论
快来发表一下你的评论吧 !