性能分析器
要设置 Performance Analyzer 的全局首选项,请转至首选项>Analyzer >CPU Usage 。
要为特定运行配置设置首选项,请转至Projects >Run ,然后选择Performance Analyzer Settings 旁边的Details 。
要编辑当前运行配置的设置,请选择性能分析仪工具栏上 旁边的下拉菜单。
选择事件类型
事件表中列出了触发性能分析仪采样的事件。分析 CPU 使用情况的最常见方法是定期采样,由硬件性能计数器驱动,这些计数器会对执行的指令数或 CPU 周期做出反应。您也可以选择使用 CPU 时钟的软件计数器。
选择Add Event ,向表中添加事件。在Event Type 中,选择要采样的事件的一般类型,最常见的是hardware 或software 。在Counter 中,选择采样的计数器。例如,hardware 组中的instructions 或software 组中的cpu-clock 。
还可以进行更专业的采样,例如按缓存未命中或缓存命中进行采样。不过,对它的支持取决于 CPU 的特定功能。对于这些特殊事件,可在Operation 和Result 中提供更详细的采样说明。例如,在结果为misses 的load 操作上为L1-dcache 选择cache 事件,以采样读取时的 L1 缓存未命中。
选择Remove Event ,从表中删除所选事件。
选择Use Trace Points ,用目标设备上定义的跟踪点替换当前选择的事件,并将Sample mode 设置为event count ,将Sample period 设置为1
。如果Create Trace Points 定义了目标设备上的跟踪点,Performance Analyzer 将自动使用它们来剖析内存使用情况。
选择Reset 可将事件选择以及Sample mode 和Sample period 恢复为默认值。
选择采样模式和周期
在Sample mode 和Sample period 中,指定采样触发方式:
- 通过event count 取样会指示内核在所选事件之一发生时每隔
n
取样一次,其中n
在Sample period 中设置。 - 通过frequency (Hz) 取样指示内核通过自动调整取样周期,尝试每秒取样
n
次。在Sample period 中设置n
。
高频率或低事件计数可获得更准确的数据,但代价是开销更大,生成的数据量更大。实际采样周期由目标设备上的 Linux 内核决定,该内核仅将为 Perf 设置的周期作为建议。您请求的采样周期与实际结果可能会有很大差异。
一般来说,如果将 Performance Analyzer 配置为收集的数据量超过其通过目标设备和主机设备之间的连接所能传输的数据量,应用程序可能会在 Perf 试图发送数据时被阻塞,处理延迟可能会过度增加。这时应更改Sample period 或Stack snapshot size 的值。
选择调用图表模式
在Call graph mode 中,您可以指定 Performance Analyzer 从应用程序中恢复调用链的方式:
- Frame Pointer 或
fp
模式依赖于剖析应用程序中可用的帧指针,并将指示目标设备上的内核遍历帧指针链,以检索每个样本的调用链。 - Dwarf 模式也不使用帧指针,但生成的数据要多得多。每次触发采样时,它都会获取当前应用程序栈的快照,并将快照传输到主机进行分析。
- Last Branch Record 模式不使用内存缓冲区。每次执行停止时,它都会自动解码最后 16 个分支。只有最新的英特尔 CPU 才支持该模式。
Qt 和大多数系统库在编译时默认不使用帧指针,因此帧指针模式只适用于定制系统。
设置堆栈快照大小
Performance Analyzer 会分析和解除Perf 在侏儒模式下生成的堆栈快照。请在Stack snapshot size 中设置堆栈快照的大小。堆栈快照越大,需要传输和处理的数据量就越大。较小的堆栈快照可能无法捕捉到高递归应用程序的调用链或其他堆栈密集使用情况。
为 Perf 添加命令行选项
在Additional arguments 中记录数据时,设置其他命令行选项以传递给 Perf。设置--no-delay
或--no-buffering
可减少处理延迟。不过,并非所有版本的 Perf 都支持这些选项,如果给出不支持的选项,Perf 可能无法启动。
解析 JIT 编译的 JavaScript 函数名称
自 5.6.0 版起,Qt 可以生成包含 JavaScript 函数信息的 perf.map 文件。性能分析器将读取它们,并在Timeline 、Statistics 和Flame Graph 视图中显示函数名称。只有当被分析的进程运行在主机而非目标设备上时,该功能才会起作用。要打开 perf.map 文件的生成,请将环境变量QV4_PROFILE_WRITE_PERF_MAP
添加到Run Environment ,并将其值设置为1
。
分析收集的数据
Timeline 视图以图形方式显示每个线程的 CPU 使用情况以及所有记录事件的浓缩视图。
时间轴中的每个类别都描述了应用程序中的一个线程。将光标移至一行中的事件 (5) 上,可查看其耗时以及所代表的源代码中的哪个函数。要只在选择事件时显示信息,请关闭View Event Information on Mouseover (4)。
大纲 (9) 概括了数据收集的时间段。拖动缩放范围 (7) 或选择大纲可在大纲上移动。您还可以通过选择Jump to Previous Event 和Jump to Next Event (1) 在事件之间移动。
选择Show Zoom Slider 按钮 (2),打开一个设置缩放级别的滑块。您还可以拖动缩放手柄 (8)。要重置默认缩放级别,请右键单击时间线打开上下文菜单,然后选择Reset Zoom 。
选择事件范围
选择一个事件范围 (6) 以查看其代表的时间或放大到跟踪的特定区域。选择Select Range (3) 激活选择工具。然后在时间轴上单击,指定事件范围的起点。拖动选择柄来定义范围的终点。
使用事件范围还可以测量两个后续事件之间的延迟。在第一个事件的结束和第二个事件的开始之间放置一个范围。Duration 显示事件之间的延迟,单位为毫秒。
要放大事件范围,请双击该范围。
要删除事件范围,请关闭Selection 对话框。
了解数据
一般来说,时间线视图中的事件表示函数调用所花费的时间。将鼠标移至事件上可查看详细信息。详细信息始终包括函数的地址、调用的大致持续时间、函数所在的 ELF 文件、在此函数调用激活时收集的样本数、在线程中遇到此函数的总次数,以及此函数至少遇到一次的样本数。
对于调试信息可用的函数,详细信息包括源代码中的位置和函数名称。您可以选择此类事件,将代码编辑器中的光标移动到事件相关的代码部分。
由于 Perf 工具只收集周期性样本,因此 Performance Analyzer 无法确定函数被调用或返回的确切时间。不过,您可以在每个线程的第二行看到采样的确切时间。性能分析器认为,如果在多个连续样本中,同一函数出现在调用链的同一位置,则表示对相应函数的一次调用。当然,这只是一种简化。此外,在采集的样本之间可能还有其他函数被调用,而这些函数并没有显示在配置文件数据中。不过,从统计角度看,这些数据可能会最显著地显示花费 CPU 时间最多的函数。
如果遇到没有调试信息的函数,堆栈的进一步解卷可能会失败。对于某些用汇编语言实现的符号,解卷也会失败。如果解卷失败,只会显示调用链的一部分,而周围的函数可能看起来被中断了。这并不一定意味着它们在应用程序执行过程中被中断,而只是在解卷失败的堆栈中找不到它们。
在 JIT 模式下运行的 QML 引擎中的 JavaScript 函数可以解卷。不过,它们的名称只有在QV4_PROFILE_WRITE_PERF_MAP
设置时才会显示。由 Qt Quick Compiler生成的编译 JavaScript 也可以解卷。在这种情况下,JavaScript 函数将显示编译器生成的 C++ 名称,而不是 JavaScript 名称。在解释模式下运行时,涉及 QML 的堆栈帧也可以展开,显示解释器本身,而不是解释后的 JavaScript。
调用链中包含的内核函数显示在每个线程的第三行。
事件的颜色代表其所属特定线程在整个持续时间内的实际采样率。只有当线程处于活动状态时,Linux 内核才会对该线程进行采样。同时,内核会尽量遵守所请求的事件周期。因此,不同线程之间采样频率的差异表明,采样次数较多的线程更有可能是整体瓶颈,而采样次数较少的线程很可能在等待 I/O 或互斥等外部事件上花费了时间。
查看统计数据
Statistics 视图显示时间线中每个函数所包含的样本数,包括总样本数和位于堆栈顶部时的样本数(称为self
)。这样就可以检查哪些函数需要优化。出现次数多可能表明函数被不必要地触发或执行时间过长。
在代码编辑器中选择一行移动到源代码中的相应函数。
Callers 和Callees 面板显示函数之间的依赖关系。通过它们可以检查应用程序的内部功能。Callers 窗格汇总了调用主视图中所选函数的函数。Callees 窗格汇总了从主视图中所选函数调用的函数。
选择一行可移动到代码编辑器源代码中的相应函数,并在主视图中选择该函数。
要将一个视图或一行的内容复制到剪贴板,请在上下文菜单中选择Copy Table 或Copy Row 。
将统计数据可视化为火焰图
Flame Graph 视图显示了更简洁的执行统计概览。水平条形图显示的是某个函数样本的某个方面,相对于所有样本的相同方面。嵌套显示哪些函数被其他函数调用。
Visualize 按钮可让您选择在Flame Graph 中显示的方面。
- Samples 是默认的可视化方式。水平条的大小表示特定函数记录的样本数。
- 在Peak Usage 模式下,水平条的大小表示各函数在内存分配使用量达到峰值时分配的内存量。
- 在Allocations 模式下,水平条的大小表示各函数触发的内存分配次数。
- 在Releases 模式下,横条的大小代表相应函数触发的内存释放次数。
只有记录了内存跟踪点的样本,Peak Usage 、Allocations 和Releases 模式才会显示任何数据。
视图之间的交互
在Timeline 、Flame Graph 或Statistics 视图中选择堆栈帧时,其他两个视图也会显示相关信息。要在Statistics 和Flame Graph 视图中查看时间范围,请选择Analyze >Performance Analyzer Options >Limit to the Range Selected in Timeline 。要显示整个堆栈帧,请选择Show Full Range 。
加载运行数据文件
您可以加载由最近版本的 Linux Perf 工具生成的任何perf.data
文件,并在Qt Creator 中查看它们。选择Analyze >Performance Analyzer Options >Load perf.data File 加载文件。
Performance Analyzer 需要知道记录数据的上下文才能找到调试符号。因此,您必须指定应用程序的构建工具包和应用程序可执行文件所在的文件夹。
Perf 数据文件通过调用perf record
生成。使用--call-graph
选项启动 Perf,确保在记录数据时生成调用图。还要检查 Performance Analyzer 是否可以使用必要的调试符号,可以是标准位置(/usr/lib/debug
或二进制文件旁边),也可以是您使用的 Qt 软件包的一部分。
Performance Analyzer 可以读取以帧指针或矮子模式生成的 Perf 数据文件。不过,要正确生成文件,必须满足许多前提条件。支持的嵌入式平台的所有系统映像都已正确设置为在 dwarf 模式下进行剖析。对于其他设备,请检查perf report
或perf script
的输出,查看记录的 Perf 数据文件,检查 Perf 是否能以合理的方式读回自己的数据。
加载和保存跟踪文件
您可以用性能分析仪专用的格式(.ptq)保存和加载跟踪数据。这种格式自成一体,因此加载时无需指定记录环境。您可以将此类跟踪文件传输到另一台没有任何工具链或调试符号的计算机上,并在那里进行分析。
要加载跟踪数据,请访问Analyze >Performance Analyzer Options >Load Trace File 。
要保存跟踪数据,请选择Save Trace File 。
故障排除
由于以下原因,Performance Analyzer 可能无法记录数据:
- 您的系统可能全局禁用了 Perf 事件。预配置的 Boot to Qt映像已启用 Perf 事件。要进行自定义配置,您需要确保文件
/proc/sys/kernel/perf_event_paranoid
包含的值小于2
。要获得记录跟踪的最大灵活性,您可以将该值设置为-1
。这允许任何用户记录任何类型的跟踪,甚至使用原始内核跟踪点。启用 Perf 事件的方法取决于 Linux 发行版。在某些发行版上,可以使用 root(或同等权限)运行以下命令:
echo -e "kernel.perf_event_paranoid=-1\nkernel.kptr_restrict=0" | sudo tee /etc/sysctl.d/10-perf.conf
- 目标设备与主机之间的连接速度可能不足以传输 Perf 生成的数据。请尝试修改Stack snapshot size 或Sample period 的设置值。
- Perf 可能一直在缓冲数据,从未发送数据。将
--no-delay
或--no-buffering
添加到Additional arguments 。 - 某些版本的 Perf 除非给定一定的最低采样频率,否则不会开始记录。请尝试将Sample period 设置为 1000。
- 在某些设备上,尤其是各种 i.MX6 板上,硬件性能计数器功能失常,Linux 内核可能会在一段时间后随机地无法记录数据。Perf 可以使用不同类型的事件来触发采样。在设备上运行
perf list
,然后在设置中选择相应的事件类型,即可获得可用事件类型列表。事件类型的选择会影响采样的性能和稳定性。cpu-clock
software
事件是一种安全但相对较慢的选择,因为它不使用硬件性能计数器,而是从软件驱动采样。采样失败后,重新启动设备。内核可能禁用了性能计数器系统的重要部分。 - 可能没有安装 Perf。安装方法取决于您的 Linux 发行版。例如,请尝试执行以下命令:
- 在 Ubuntu 22.04 上
sudo apt install linux-tools-$(uname -r)
- 在 Debian 上
apt install linux-perf
- 在 Ubuntu 22.04 上
General Messages 视图显示处理数据的辅助程序的输出。
即使性能分析器显示错误信息,应用程序输出视图也会显示一些信息。
Copyright © The Qt Company Ltd. and other contributors. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.