跳至内容

穷人取样分析仪

本节将介绍如何使用 穷人取样分析仪 (PMSP) shell 脚本来评估 PX4 的性能。这是对最初由 马克-卡拉汉和多马斯-米图扎斯.

方法

PMSP 是一个 shell 脚本,通过定期中断固件的执行来对当前堆栈跟踪进行采样。取样的堆栈跟踪会被添加到文本文件中。采样完成后(通常需要一小时或更长时间),收集到的堆栈跟踪会被保存到一个文本文件中。 褶皱的.结果是 褶皱 是另一个包含相同堆栈轨迹的文本文件,但所有相似的堆栈轨迹(即在程序中同一时刻获得的堆栈轨迹)都被合并在一起,并记录了它们的出现次数。然后将折叠后的堆栈输入可视化脚本,为此我们使用了 FlameGraph - 一种开源堆栈跟踪可视化工具.

基本用法

先决条件

剖析器依靠 GDB 在嵌入式目标机上运行 PX4。因此,在对目标进行剖析之前,您必须拥有要剖析的硬件,并且必须编译固件并上传到该硬件。然后,您需要一个 调试探针 (例如 DroneCode Probe),以运行 GDB 服务器并与电路板交互。

确定调试器设备

poor-mans-profiler.sh 自动检测并使用正确的 USB 设备。 无人机代码探测器.如果您使用的是另一种探针,可能需要输入特定的 装置 上的调试器。您可以使用 bash 命令 ls -alh /dev/serial/by-id/ 来枚举 Ubuntu 上可能的设备。例如,通过 USB 连接 Pixhawk 4 和 DroneCode 探针后,可枚举出以下设备:

user@ubuntu:~/PX4-Autopilot$ ls -alh /dev/serial/by-id/
总计 0
drwxr-xr-x 2 根基 根基 100 Apr 23 18:57 .
drwxr-xr-x 4 根基 根基  80 Apr 23 18:48 ..
lrwxrwxrwx 1 根基 根基  13 Apr 23 18:48 usb-3D_Robotics_PX4_FMU_v5.x_0-if00 ->; ../../ttyACM0
lrwxrwxrwx 1 根基 根基  13 Apr 23 18:57 usb-Black_Sphere_Technologies_Black_Magic_Probe_BFCCB401-if00 ->; ./././ttyACM1
lrwxrwxrwx 1 根基 根基  13 Apr 23 18:57 usb-Black_Sphere_Technologies_Black_Magic_Probe_BFCCB401-if02 ->; ./././ttyACM2

在这种情况下,脚本会自动拾取名为 *Black_Magic_Probe*-if00.但如果您使用的是其他设备,您可以从上面的列表中找到相应的 ID。

然后使用 -gdbdev 这样的论点:

./poor-mans-profiler.sh --elf=build/px4_fmu-v4_default/px4_fmu-v4_default.elf --样本数=30000 -gdbdev=/dev/ttyACM2

跑步

剖析器的基本用法可通过构建系统实现。例如,以下命令可构建并剖析具有 10000 个样本的 px4_fmu-v4pro 目标机(获取 FlameGraph 并根据需要将其添加到路径中)。

生产 px4_fmu-v4pro_default 概况

要对构建过程进行更多控制,包括设置样本数量,请参阅 实施情况.

了解输出

下面是输出示例的截图(注意这里不是交互式的):

FlameGraph 示例

在火焰图上,水平层代表堆栈帧,而每个帧的宽度与采样次数成正比。反过来,函数最终被采样的次数与函数执行的持续时间乘以频率成正比。

可能出现的问题

该脚本是作为临时解决方案开发的,因此存在一些问题。使用时请注意:

  • 如果 GDB 出现故障,脚本可能无法检测到,并继续运行。在这种情况下,显然不会产生可用的堆栈。为了避免这种情况,用户应该定期检查文件 /tmp/pmpn-gdberr.log,其中包含最近一次调用 GDB 的 stderr 输出。将来应该修改脚本,以便在安静模式下调用 GDB,并通过退出代码显示问题。

  • 有时,GDB 在对堆栈跟踪进行采样时会永远停止。在此故障期间,目标将无限期停止。解决方法是手动中止脚本,然后使用 --附加 选项。今后应修改脚本,使每次调用 GDB 时都有一个超时时间。

  • 不支持多线程环境。这不会影响单核嵌入式目标,因为它们总是在一个线程中执行,但这一限制使得剖析器与许多其他应用程序不兼容。今后应修改堆栈文件夹,以支持每个样本的多个堆栈跟踪。

实施情况

脚本位于 /platforms/nuttx/Debug/poor-mans-profiler.sh 启动后,它将以指定的时间间隔执行指定数量的采样。采集的样本将保存在系统临时目录下的文本文件中(通常为 /tmp).取样完成后,脚本将自动调用堆栈文件夹,其输出结果将保存在临时目录下的相邻文件中。如果堆栈折叠成功,脚本将调用 FlameGraph 脚本,并将结果存储到交互式 SVG 文件中。请注意,并非所有图像查看器都支持交互式图像;建议在网络浏览器中打开生成的 SVG。

FlameGraph 脚本必须位于 路径否则 PMSP 将拒绝启动。

PMSP 使用 GDB 收集堆栈跟踪。目前它使用 arm-none-eabi-gdb今后还可能增加其他工具链。

为了将内存位置映射到符号,脚本需要引用目标机上当前运行的可执行文件。这需要借助 --elf=<文件>;,它需要一个指向当前执行的 ELF 位置的路径(相对于资源库根目录)。

使用示例

./poor-mans-profiler.sh --elf=build/px4_fmu-v4_default/px4_fmu-v4_default.elf --样本数=30000

请注意,每次启动脚本都会覆盖旧堆栈。如果您想追加而不是覆盖旧堆栈,可使用选项 --附加:

./poor-mans-profiler.sh --elf=build/px4_fmu-v4_default/px4_fmu-v4_default.elf --样本数=30000 --附加

正如人们所猜测的那样、 --附加--样本数=0 将指示脚本只重新生成 SVG,而完全不访问目标。

请阅读脚本,更深入地了解其工作原理。