性能分析器
分析应用程序在 Linux 桌面和嵌入式设备上的 CPU 和内存使用情况。
要设置性能分析器的全局首选项,请转至Preferences >Analyzer >CPU Usage 。
要设置特定运行配置的偏好设置,请转到Projects >Run Settings ,然后选择“Performance Analyzer Settings ”旁边的“Details ”。

要编辑当前运行配置的设置,请选择“性能分析器”工具栏上“
”旁边的下拉菜单。

选择事件类型
“事件”表列出了触发“性能分析器”进行采样的事件。分析 CPU 使用率最常见的方法是采用周期性采样,该方法由硬件性能计数器驱动,这些计数器会对已执行的指令数或 CPU 周期数作出响应。您还可以选择使用 CPU 时钟的软件计数器。
选择“Add Event ”可向表格中添加事件。在“Event Type ”中,选择要采样的事件通用类型,最常见的是“hardware ”或“software ”。在“Counter ”中,选择用于采样的计数器。例如,“hardware ”组中的“instructions ”,或“software ”组中的“cpu-clock ”。
还可以进行更专业的采样,例如按缓存未命中或缓存命中进行采样。但是,是否支持取决于 CPU 的具体特性。对于这些特殊事件,请在Operation 和Result 中提供更详细的采样说明。例如,在load 操作中,针对结果为misses 的L1-dcache 事件,选择cache 事件,以采样读取时的 L1-dcache 未命中。
选择“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 设置的周期作为参考。您请求的采样周期与实际结果之间可能会有显著差异。
通常,如果您将性能分析器配置为收集的数据量超过目标设备与主机设备之间连接所能传输的上限,当Perf尝试发送数据时,应用程序可能会被阻塞,且处理延迟可能会过分增加。此时,您应修改Sample period 或Stack snapshot size 的值。
选择调用图模式
在Call graph mode 中,您可以指定性能分析器如何从应用程序中恢复调用链:
- Frame Pointer 或
fp模式依赖于被分析的应用程序中存在帧指针,并将指示目标设备上的内核遍历帧指针链,以便为每个采样获取调用链。 - Dwarf 模式即使没有帧指针也能工作,但会生成显著更多的数据。它会在每次触发采样时对当前应用程序堆栈进行快照,并将该快照传输到主机计算机进行分析。
- Last Branch Record 模式不使用内存缓冲区。每次执行暂停时,它都会自动解码最近执行的16个分支。该模式仅在较新的英特尔CPU上受支持。
Qt 以及大多数系统库默认编译时不包含帧指针,因此帧指针模式仅在定制系统中才有用。
设置堆栈快照大小
性能分析器(Performance Analyzer)会分析并展开由 Perf 在 dwarf 模式下生成的栈快照。请在Stack snapshot size 中设置栈快照的大小。较大的栈快照会导致需要传输和处理的数据量增大。较小的栈快照可能无法捕获高度递归应用程序或其他栈使用密集型场景的调用链。
为 Perf 添加命令行选项
在Additional arguments 中设置要传递给Perf的额外命令行选项。设置--no-delay 或--no-buffering 可减少处理延迟。但并非所有版本的Perf都支持这些选项,若指定了不受支持的选项,Perf可能无法启动。
解析 JIT 编译的 JavaScript 函数名称
自 5.6.0 版本起,Qt XML 可以生成包含 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 工具仅收集周期性采样,因此“性能分析器”无法确定函数被调用或返回的确切时间。 不过,您可以在每个线程的第二行中看到采样确切的采集时间。性能分析器假设:如果同一函数在多个连续采样中出现在调用链的同一位置,则表示对该函数进行了一次调用。当然,这是一种简化处理。 此外,在采样之间可能还调用了其他函数,但这些函数不会显示在分析数据中。不过,从统计学角度来看,数据很可能会最突出地显示那些消耗最多 CPU 时间的函数。
如果遇到没有调试信息的函数,栈的进一步展开可能会失败。 对于某些用汇编语言实现的符号,展开操作也会失败。如果展开失败,则只会显示调用链的一部分,而周围的函数可能会显得被中断。这并不一定意味着它们在应用程序执行过程中确实被中断了,而仅仅表示在展开失败的堆栈中无法找到它们。
在 JIT 模式下运行的 QML 引擎生成的 JavaScript 函数可以进行栈帧展开。但是,只有当设置了 `QV4_PROFILE_WRITE_PERF_MAP ` 时,才会显示这些函数的名称。由Qt Quick 编译器生成的编译后 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 。
加载 perf 数据文件
您可以加载由最新版本的 Linux Perf 工具生成的任何perf.data 文件,并在Qt Creator 中查看。选择Analyze >Performance Analyzer Options >Load perf.data File 即可加载文件。

性能分析器需要了解数据记录时的上下文环境,才能查找调试符号。因此,您必须指定应用程序的构建套件以及应用程序可执行文件所在的文件夹。
Perf数据文件是通过调用perf record 生成的。请确保在记录数据时生成调用图,方法是使用--call-graph 选项启动Perf。同时请确认Performance Analyzer能够访问必要的调试符号,这些符号可以位于标准位置(/usr/lib/debug 或二进制文件旁边),也可以作为您所使用的Qt软件包的一部分。
Performance Analyzer 可以读取以帧指针模式或 dwarf 模式生成的 Perf 数据文件。但是,要正确生成这些文件,必须满足许多先决条件。 所有受支持的嵌入式平台系统镜像均已正确配置,支持以 dwarf 模式进行性能分析。对于其他设备,请通过检查perf report 或perf script 的输出结果,验证 Perf 能否以合理的方式读取其记录的 Perf 数据文件。
加载和保存跟踪文件
您可以使用性能分析器专用的格式(.ptq)保存和加载跟踪数据。该格式是自包含的,因此加载时无需指定记录环境。您可以将此类跟踪文件传输到另一台计算机上,无需任何工具链或调试符号,即可在该计算机上进行分析。
要加载跟踪数据,请转至Analyze >Performance Analyzer Options >Load Trace File 。
要保存跟踪数据,请选择“Save Trace File ”。
故障排除
性能分析器可能因以下原因无法记录数据:
- 您的系统上可能全局禁用了 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-clocksoftware事件是一种安全但相对较慢的选项,因为它不使用硬件性能计数器,而是通过软件驱动采样。如果采样失败,请重启设备。内核可能已禁用了性能计数器系统中的重要部分。 - 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.