环境搭建:工欲善其事,必先利其器
说实话,做嵌入式性能调优这么多年,我踩过最大的坑就是环境没搭好就开始干活。你想想看,工具链版本冲突、perf 权限不够、FlameGraph 脚本跑不出来——这些破事能浪费你一整天。所以这一章,咱们老老实实把环境搭稳了再动手。
我个人习惯把工具链分成四块:Python 虚拟环境、perf 性能分析工具、FlameGraph 可视化脚本、交叉编译工具链。每一块我都会讲安装步骤、验证方法,还有我当年踩过的坑。
2.1 Python 虚拟环境:隔离依赖的保险箱
为什么非要用虚拟环境?因为 Python 的依赖管理太容易打架了。我曾经在一个项目里同时用 TensorFlow 1.x 和 2.x,结果 pip 装完直接炸了。虚拟环境就是给每个项目一个独立的 Python 小世界。
安装步骤很简单:
# 安装 venv 模块(Python 3.3+ 自带)
sudo apt-get install python3-venv
# 创建虚拟环境
python3 -m venv perf_tool_env
# 激活环境
source perf_tool_env/bin/activate
# 验证
which python
# 输出应该指向 perf_tool_env/bin/python
激活后,你的终端前面会多一个 (perf_tool_env) 前缀。嗯,看到这个就对了。
.venv 文件夹,然后配置 IDE 自动识别。这样每次打开终端都不用手动激活,省心。
2.2 perf 工具:Linux 性能分析的瑞士军刀
perf 是内核自带的性能分析工具,能采样 CPU 周期、缓存 miss、分支预测失败等等。说白了,它就是给 CPU 装了个黑匣子,记录每一刻在干什么。
安装命令:
sudo apt-get install linux-tools-common linux-tools-generic
sudo apt-get install linux-tools-$(uname -r)
验证是否装好:
perf --version
# 输出类似:perf version 5.15.0
--privileged 模式。建议直接在物理机或原生 Linux 上跑。
验证 perf 能否采样:
# 跑一个简单的采样测试
perf stat sleep 1
# 输出应该包含类似:
# 1.002 seconds time elapsed
如果报 perf_event_open 权限错误,别慌。这是因为内核限制了非 root 用户访问性能计数器。解决方案:
# 临时方案
sudo perf stat sleep 1
# 永久方案(我推荐这个)
echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
2.3 FlameGraph 脚本集:把枯燥数据变成火焰图
FlameGraph 是 Brendan Gregg 大神写的 Perl 脚本集。它能把你用 perf 采集的调用栈数据,渲染成一张火焰图。火焰图越长,说明那个函数占用的 CPU 时间越多——一眼就能看出热点在哪。
下载脚本:
git clone https://github.com/brendangregg/FlameGraph.git
cd FlameGraph
验证脚本是否可用:
# 检查 Perl 环境
perl -v
# 测试一个脚本
./stackcollapse-perf.pl --help
# 应该输出帮助信息
Data::Dumper。如果你遇到 Can't locate Data/Dumper.pm 错误,执行 sudo cpan Data::Dumper 装上就行。
完整的工作流是这样的:
# 1. 用 perf 采集数据
perf record -F 99 -a -g -- sleep 30
# 2. 生成 perf 数据文件
perf script > out.perf
# 3. 折叠调用栈
./stackcollapse-perf.pl out.perf > out.folded
# 4. 生成 SVG 火焰图
./flamegraph.pl out.folded > flame.svg
最后用浏览器打开 flame.svg,你就能看到绚丽的火焰图了。鼠标悬停在某个色块上,会显示函数名和占比。
2.4 交叉编译工具链:让代码在目标板上跑起来
嵌入式开发嘛,你的 PC 是 x86 架构,目标板可能是 ARM、RISC-V 或者 MIPS。交叉编译就是在 PC 上编译出目标板能运行的二进制文件。
以 ARM Cortex-A 系列为例,安装交叉编译工具链:
# 安装 ARM 交叉编译器
sudo apt-get install gcc-arm-linux-gnueabihf
sudo apt-get install g++-arm-linux-gnueabihf
验证安装:
arm-linux-gnueabihf-gcc --version
# 输出类似:arm-linux-gnueabihf-gcc (Ubuntu 9.3.0) 9.3.0
写一个简单的测试程序:
// hello.c
#include <stdio.h>
int main() {
printf("Hello from ARM!\n");
return 0;
}
交叉编译:
arm-linux-gnueabihf-gcc -o hello_arm hello.c
验证生成的文件:
file hello_arm
# 输出应该包含:ELF 32-bit LSB executable, ARM, version 1 (SYSV)
Exec format error。嗯,别学我。
2.5 环境验证清单
为了确保所有工具都正常工作,我整理了一个验证清单。每完成一项就打个勾:
| 工具 | 验证命令 | 预期结果 |
|---|---|---|
| Python 虚拟环境 | python3 -m venv test_env && source test_env/bin/activate && which python |
路径指向 test_env/bin/python |
| perf 工具 | perf stat sleep 1 |
输出性能计数器数据 |
| FlameGraph 脚本 | ./flamegraph.pl --help |
显示帮助信息 |
| 交叉编译工具链 | arm-linux-gnueabihf-gcc --version |
显示版本号 |
我的建议: 把上面四个验证命令写成一个 shell 脚本,每次换新机器或者重装系统后跑一遍。我自己的 check_env.sh 脚本已经用了三年,省了我不少排查时间。
2.6 常见问题与解决
环境搭建过程中,你可能会遇到这些问题。我把它们列出来,方便你对照排查:
- perf 报权限错误:执行
sudo sysctl -w kernel.perf_event_paranoid=-1临时解决,或者永久写入/etc/sysctl.conf。 - FlameGraph 脚本报 Perl 模块缺失:用
cpan安装缺失模块,或者直接安装libdata-dumper-perl包。 - 交叉编译工具链找不到:检查
PATH环境变量是否包含/usr/bin,或者用绝对路径调用。 - 虚拟环境激活后 pip 还是全局的:确保你激活了环境,并且
pip是pip3的软链接。可以用which pip确认。
好了,环境搭建就到这里。下一章我们会用 perf 采集第一个性能数据,然后生成火焰图。到时候你会发现,前面这些准备工作都是值得的。