ffx profiler 是一种工具,可用于查找和直观呈现代码中的热点。CPU 性能分析器会定期对正在运行的线程进行抽样并记录回溯,您可以使用 pprof 工具查看这些回溯。
何时使用 ffx profiler
CPU 分析器最适合用于确定一段时间内 CPU 时间的分配情况。通过频繁采集堆栈样本,性能分析器可以构建执行情况的统计视图,帮助您找到性能瓶颈(“热点”),而无需修改或检测代码。
- 如果您想了解系统或特定组件中哪些函数消耗的 CPU 时间最多,请使用
ffx profiler。 - 当您需要了解事件的顺序流、特定操作之间的延迟时间或不同进程(例如 IPC)随时间推移的互动时,请使用
ffx trace。如需进行跟踪,开发者必须向源代码添加轨迹事件,才能使跟踪生效。 - 当您需要检查确切的执行状态、逐步执行代码或分析特定时间点的内存以了解正确性问题时,请使用
zxdb(调试器)。
前提条件和设置
为了以最低的观察者开销获得最准确的配置文件,请始终使用启用了内核辅助线程采样器的正式版 build。
build 的重要性--release
始终针对 --release build 进行分析。调试 build 缺少内联和优化传递。对于 Rust 和 C++ 等语言,除非应用了优化,否则其标准库中的“零成本抽象”并非零成本。对调试 build 进行分析会生成一个以内部标准库调用(例如迭代器和 Option 处理)为主的配置文件,而不是实际的应用逻辑。
虽然由于内联,发布 build 可能会使堆栈难以跟踪,但它们可以准确反映实际性能。
启用内核辅助采样
内核辅助采样可显著减少获取堆栈样本的开销。向 fx set 命令添加以下实参:
fx set <PRODUCT>.<BOARD> \
--release \
--args='experimental_thread_sampler_enabled=true'常见使用场景和示例
系统范围的性能分析
如需分析设备上运行的所有内容(包括根作业及其所有后代),请使用 --system-wide 标志:
ffx profiler attach --system-wide --duration 10此命令将运行 10 秒,并生成一个 profile.pb 文件。
运行测试并进行分析
您可以指示分析器启动测试组件并分析其执行情况,直到完成为止。请注意,目标软件包必须在您的 build 图中可用(如果它是新的或可选的测试,您可能需要使用 fx with 或 fx add-test 显式添加它并重新构建)。使用 --test 标志:
ffx profiler launch \
--url "fuchsia-pkg://fuchsia.com/gtest_target#meta/gtest_target.cm" \
--test如需分析相应软件包中的特定测试用例,请使用 --test-filters:
ffx profiler launch \
--url "fuchsia-pkg://fuchsia.com/gtest_target#meta/gtest_target.cm" \
--test \
--test-filters "GtestTest.MakeWorkTest"后台分析(断开与主机的连接)
有时,您需要分析与宿主机断开连接时发生的事件,例如在挂起/恢复周期内。为此,请在后台运行分析器会话。
在后台启动个人资料:
ffx profiler attach --system-wide --backgroundCLI 会输出确认信息,例如:
Background session started. task_id: 1您的设备现在会在后台持续记录分析器样本。
断开主机连接、触发挂起或执行您希望测量的操作。等待设备唤醒并重新连接到主机。
停止会话并下载配置文件。此命令将查找正在运行的后台会话,停止该会话,并将数据下载到主机:
ffx profiler stopWrote profile to profile.pb
启动时进行性能分析
您可以配置分析器,使其在下次设备重启时,在进程启动后立即附加到进程。这有助于分析早期启动性能或启动序列。
启动以下次启动为目标的配置文件会话:
ffx profiler attach --system-wide --on-bootCLI 将输出确认信息,例如:
On-boot profiling session configured. Profiles will be collected when the target component starts.重新启动设备。
等待设备完成启动并启动目标进程。您可以使用
status命令检查有效会话的状态。停止会话以下载累积的配置文件:
ffx profiler stop
检查分析器状态
如需查看当前在设备上运行的任何有效的后台或启动时分析会话,请使用 status 命令:
ffx profiler statusActive background sessions:
- task_id: 1
附加到现有进程
您可以附加到特定组件或进程。
按组件网址或 Moniker:
首先,找到目标组件的 moniker。您可以使用 ffx component list 列出当前在系统上运行的所有组件:
ffx component list.
bootstrap
bootstrap/archivist
bootstrap/archivist/archivist-pipelines
...
core/your_component
然后使用生成的 moniker 进行附加:
ffx profiler attach --moniker core/your_component或者,您也可以使用组件的软件包网址进行附加:
ffx profiler attach --url 'fuchsia-pkg://fuchsia.com/your_component#meta/your_component.cm'按 KOID(PID/TID/作业 ID):首先,利用设备上的 ps 命令找到目标的进程 ID (PID):
ffx target ssh psTASK PSS PRIVATE SHARED STATE NAME
j: 1045 620.7M 464.7M root
p: 1122 17.7M 17.7M 4944K bin/component_manager
...
j: 1944 126.0K 24K
p: 1993 126.0K 24K 5076K kernel-args-forwarder.cm
然后,附加到生成的 PID(在此示例中,kernel-args-
forwarder.cm 的 PID 为 1993):
ffx profiler attach --pids 1993 --duration 5(指定 PID 会自动分析相应进程中的所有线程)。
命令行参数和最佳实践
以下选项适用于 ffx profiler attach、ffx profiler
launch 和 ffx profiler stop:
--output:输出跟踪文件的名称或路径。默认设置为profile.pb。--print-stats:将有关剖析会话的统计信息打印到标准输出。--color-output:如果为 true,则在输出中包含颜色代码。如果检测到终端输出,则默认为 true。
以下选项适用于 ffx profiler attach 和 ffx profiler
launch:
- 采样周期 (
--sample-period-us):默认采样周期为10000微秒(10 毫秒)。减小此值(例如,减小到 1 毫秒)可提供更高的分辨率,但会增加分析器本身的 CPU 开销,从而可能会改变您尝试测量的系统行为(“观察者效应”)。 - 缓冲区空间 (
--buffer-size-mb):如果您要长时间分析高度活跃的系统,则可能会在性能分析器完成捕获之前耗尽默认缓冲区空间。如果您遇到缺少样本或警告的情况,请增加内存分配。 - 时长 (
--duration):如果未指定--duration,分析器将以交互方式运行,并等待您按<ENTER>停止捕获。 - 后台 (
--background):在后台运行分析器会话。
以下选项仅适用于 ffx profiler attach:
- 启动时 (
--on-boot):在设备下次启动时运行分析器会话。
还有其他选项可供选择。这些标志主要用于对分析器进行问题排查,并提供对分析器执行的精细控制。 如需了解详情,请参阅 ffx 分析器参考文档。
分析个人资料
分析器停止后,会在当前目录中生成一个 profile.pb 文件。您可以使用 Perfetto 界面或 Google 的 pprof 工具分析此文件。
Perfetto 界面(推荐)
您可以将 profile.pb 直接上传到 Perfetto 界面,以便在浏览器中直观呈现配置文件。这通常是探索个人资料最直观且功能最丰富的方式。
使用 pprof 的互动式网页界面
您还可以使用 pprof 的交互式网页界面,其中包含图形火焰图。
pprof -http=localhost:8080 profile.pb浏览器将打开并显示 http://localhost:8080。在顶部菜单中,您可以选择以下视图:
- Top:显示消耗最多扁平 CPU 时间的函数。
- 火焰图:直观地表示调用堆栈层次结构。方框的宽度表示对相应函数或其子函数进行抽样所花费的总时间。
终端热门功能
如需将热门函数直接快速输出到终端,请执行以下操作:
pprof -top profile.pb此命令会生成文本输出,其中显示了平百分比和累计百分比:
Showing nodes accounting for 272, 100% of 272 total
flat flat% sum% cum cum%
243 89.34% 89.34% 243 89.34% count(int)
17 6.25% 95.59% 157 57.72% main()
4 1.47% 97.06% 4 1.47% collatz(uint64_t*)
3 1.10% 98.16% 3 1.10% add(uint64_t*)
3 1.10% 99.26% 3 1.10% sub(uint64_t*)
1 0.37% 99.63% 1 0.37% rand()
- 扁平:此函数在堆栈顶部处于活跃执行状态的样本数量。
- cum:此函数正在执行或其任何后代正在执行的样本数。