Linux perf
perf
,那是什么? perf, what’s that? section" href="#perf-whats-that">
Linux perf
工具是一个非常强大的工具,它可以用于:
- 对 CPU 密集型进程(或整个系统)进行采样,以分析应用程序的哪个部分正在消耗 CPU 时间
- 访问 CPU 性能计数器 (PMU)
- “用户探针”(uprobes),例如当应用程序中的某个特定函数运行时触发
通常,perf
可以在特定事件发生时计数和/或记录线程的调用堆栈。这些事件可以由以下因素触发:
- 时间(例如,每秒 1000 次),可用于时间分析。有关使用示例,请参阅CPU 性能调试指南。
- 系统调用,可用于查看系统调用的发生位置。
- 各种系统事件,例如,如果您想知道何时发生上下文切换。
- CPU 性能计数器,如果您可以将性能问题追溯到 CPU 的微架构细节(例如分支预测错误),这将非常有用。有关示例,请参阅 SwiftNIO 的高级性能分析指南。
- 以及更多
让 perf
工作起来 perf to work section" href="#getting-perf-to-work">
不幸的是,让 perf
工作取决于您的环境。下面,请查找一些环境以及如何在这些环境中使 perf
工作。
安装 perf
perf section" href="#installing-perf">
从技术上讲,perf
是 Linux 内核源代码的一部分,您会希望 perf
版本与您的 Linux 内核版本完全匹配。但在许多情况下,“足够接近”的 perf
版本也可以。 如果有疑问,请使用比您的内核版本稍旧的 perf
版本,而不是更新的版本。
-
Ubuntu
apt-get update && apt-get -y install linux-tools-generic
有关更多信息,请参见下文,因为 Ubuntu 为每个内核版本打包了不同的
perf
。 -
Debian
apt-get update && apt-get -y install linux-perf
-
Fedora/RedHat 衍生版本
yum install -y perf
您可以使用 perf stat -- sleep 0.1
(如果您已经是 root
用户)或 sudo perf stat -- sleep 0.1
来确认您的 perf
安装是否正常工作。
当您无法匹配内核版本时 Ubuntu 上的 perf
perf on Ubuntu when you can’t match the kernel version section" href="#perf-on-ubuntu-when-you-cant-match-the-kernel-version">
在 Ubuntu 上(以及其他每个内核版本打包 perf
的发行版),安装 linux-tools-generic
后,您可能会看到错误。错误消息将类似于
$ perf stat -- sleep 0.1
WARNING: perf not found for kernel 5.10.25
You may need to install the following packages for this specific kernel:
linux-tools-5.10.25-linuxkit
linux-cloud-tools-5.10.25-linuxkit
You may also want to install one of the following packages to keep up to date:
linux-tools-linuxkit
linux-cloud-tools-linuxkit
解决此问题的最佳方法是按照 perf
的提示安装上述软件包之一。如果您在 Docker 容器中,这可能不可行,因为您需要匹配内核版本(这在 Docker for Mac 中尤其困难,因为它使用 VM)。 例如,建议的 linux-tools-5.10.25-linuxkit
实际上不可用。
作为一种解决方法,您可以尝试以下选项之一
-
如果您已经是
root
用户并且喜欢 shellalias
(仅在此 shell 中有效)alias perf=$(find /usr/lib/linux-tools/*/perf | head -1)
-
如果您是用户并且希望首选链接
/usr/local/bin/perf
sudo ln -s "$(find /usr/lib/linux-tools/*/perf | head -1)" /usr/local/bin/perf
完成此操作后,您应该能够成功使用 perf stat -- sleep 0.1
(如果您已经是 root
用户)或 sudo perf stat -- sleep 0.1
。
裸机
对于裸机 Linux 机器,您只需安装 perf
,它应该可以完全正常工作。
在 Docker 中(在裸机 Linux 上运行)
您将需要使用 docker run --privileged
启动容器(请勿在生产环境中运行),然后您应该可以完全访问 perf(包括 PMU)。
要验证 perf
是否正常工作,请运行例如 perf stat -- sleep 0.1
。您是否会在某些信息旁边看到 <not supported>
取决于您是否可以访问 CPU 的性能计数器 (PMU)。在裸机上的 Docker 中,这应该可以工作,即不应显示 <not supported>
。
Docker for Mac
Docker for Mac 类似于裸机上的 Docker,但由于我们实际上是在 Linux VM 中托管的 Docker 容器中运行,因此会增加一些复杂性。因此,匹配内核版本将很困难。
如果您按照上述安装说明进行操作,您仍然应该能够使 perf
工作,但您将无法访问 CPU 的性能计数器 (PMU),因此您会看到一些事件显示为 <not supported>
。
$ perf stat -- sleep 0.1
Performance counter stats for 'sleep 0.1':
0.44 msec task-clock # 0.004 CPUs utilized
1 context-switches # 0.002 M/sec
0 cpu-migrations # 0.000 K/sec
57 page-faults # 0.129 M/sec
<not supported> cycles
<not supported> instructions
<not supported> branches
<not supported> branch-misses
0.102869000 seconds time elapsed
0.000000000 seconds user
0.001069000 seconds sys
在虚拟机中
在虚拟机中,您将像在裸机上一样安装 perf
。并且 perf
将可以正常工作并具有所有功能,或者它看起来类似于您在 Docker for Mac 上获得的效果。
您需要您的虚拟机监控程序支持(并允许)的是“PMU 直通”或“PMU 虚拟化”。VMware Fusion 支持 PMU 虚拟化,他们称之为 vPMC(VM 设置 -> 处理器和内存 -> 高级 -> 允许此 VM 中的代码分析应用程序)。如果您使用的是 Mac,则不幸的是,此设置仅支持到包括 macOS Catalina(并且 不支持 Big Sur)。
如果您使用 libvirt
来管理您的虚拟机监控程序和 VM,您可以使用 sudo virsh edit your-domain
并将 <cpu .../>
XML 标记替换为
<cpu mode='host-passthrough' check='none'/>
以允许 PMU 传递到访客操作系统。 对于其他虚拟机监控程序,互联网搜索通常会揭示如何启用 PMU 直通。