简单的活着

Intel-PT

Posted on By Mista Cai

Intel Processor Tracing

介绍

Intel PT是Intel处理器的一项新功能,可提供机器指令级跟踪。 这有助于对程序进行低级调试和性能分析,甚至可以恢复崩溃应用程序的状态。

本文记录了英特尔PT的基本设计概念,Linux平台的要求以及一些性能测量用例。

1概述

Linux操作系统具有大量的跟踪工具。kprobesuprobeskernel tracepointsdtrace探针都是捕获数据的数据源。 ftraceeBPFperfSystemTapLTTng是提取数据并为用户提供前端的工具。这些可以用于hook运行程序并分析它们的行为(系统调用,在函数中花费的时间或等待/阻塞等指标)。Intel PT是另一种数据源,但它是CPU性能监控单元(PMU)内部的专用并行硬件,用于跟踪CPU上运行的软件。它跟踪每个内核上的分支执行,允许用户重建所有执行代码的控制流。

然而,随着现代CPU的速度(每秒数十亿个时钟周期),将收集的数据存储在任何地方变得具有挑战性,因为缓冲区要么不够快或太小(内存层次结构)。Intel PT通过仅存储以后重构程序控制流所必需的数据来解决此问题。例如,条件分支仅存储为单个位(taken/not-taken)。它还捕获某些处理器执行模式更改(例如CR3,32位/ 64位模式和TSX事务状态)和时序。

用于跟踪的专用硬件和高度压缩的跟踪流的组合使得Intel PT具有非常低的开销,但是需要解码packet stream

由于Linux内核版本4.3, Intel PT完全集成到Linux操作系统中(内核驱动程序在4.1中合并,perf用户工具支持在4.3中合并)和GNU Debugger gdb(从7.10开始,启用向后调试)。

它有两种基本操作模式,但将来可能会添加更多。Full trace mode允许连续跟踪,只要磁盘保持运行就会运行(否则可能会丢失数据)。snapshot mode在特殊的环形缓冲区(由操作系统提供)中运行,停止对感兴趣的事件进行跟踪,并且仅在此时保存环形缓冲区的快照。

Intel PT首次出现在Broadwell微架构中,继微观架构(SkylakeGoldmont)之后,他们看到了细粒度定时和地址过滤等其他增强功能。它也可以在Atom平台(基于Silvermont和Airmont的产品)上获得,但在那里被称为实时指令跟踪(RTIT)。

应该注意,对于任何有意义的分析,编译器不得省略帧指针。 现代编译器重新使用帧指针寄存器(x86平台上的EBP)作为通用寄存器,并避免指令保存,设置和恢复帧指针。 但是,它使调用堆栈的重构(因此一般调试)变得不可能。 例如,gcc默认省略帧指针,但可以通过使用--fno-omit-framepointer选项来防止这种情况。

2 采集

在CPU捕获数据之后,需要获取,解码和转译数据。 提取通过Linux的perf_event接口进行,解码可以手动完成,也可以使用英特尔提供的免费开源处理器跟踪解码库(libipt)来解码数据包流。或者,也可以使用带有集成Intel PT支持的Linux perf-toolsgdb

3 Packets

Intel PT硬件将单个数据包写入日志流。 需要对这些数据包进行解码,绑定到事件,然后可以重建执行流程。 这三个步骤都在Intel PT解码库(libipt)中实现。

  1. PSB (Packet Stream Boundary): heartbeats, generated at regular intervals (first packet in stream)

  2. TNT (Taken Not-Taken): direct conditional branches

  3. TIP (Target IP): target address of indirect branches, exception and interrupts
  4. FUP (Flow Update Packets): source IP address for asynchronous events

  5. PIP (Paging Information Packet): modifications to CR3 register
  6. TSC (Time-Stamp Counter): tracks wall clock data (contains some portion of the software-visible time-stamp counter)
  7. MODE: processor execution information and mode (16-, 32- or 64-bit)
  8. CBR (Core Bus Ratio): core to bus clock ratio
  9. MWAIT: indicate successful completion of an MWAIT operation to a C-state deeper than C0.0
  10. PWRE (Power State Entry): indicate entry to a C-state deeper than C0.0
  11. PWRX (Power State Exit): indicate exit from a C-state deeper than C0.0, returning to C0.
  12. EXSTOP (Execution Stopped): indicate that software execution has stopped, due to events such as P-state change, C-state change, or thermal throttling
  13. CYC (Cycle-Accurate Mode): provides elapsed time as measured in processor core clock cycles relative to the last CYC packet (Not avail- able on Broadwell)
  14. MTC (Mini Time Counter): provides a periodic indication of wall- clock time (Not available on Broadwell)
  15. OVF (Overflow): indicates internal buffer overflow (packets being dropped)
  16. PAD: padding

对于性能分析和调试,时间戳计数器包(TSC)特别有趣。

但是,对于具有指令级粒度的跟踪,此数据包不会经常生成(其生成也无法配置)。 这是循环精确模式的应用(具有CYC数据包,其生成非常规则和频繁),因为循环计数器字段以与处理器核心时钟滴答相同的速率递增。 此功能仅适用于Skylake及其后续版本。

有关这些数据包的更多信息,请参阅英特尔软件开发人员手册第3卷[8,第35章]。

4 测试用例

4.1 性能测试

4.2 Flame Graphs

4.3 Debugging

4.4 Simple PT

Simple PT(英特尔工程师Andi Kleen)是针对Intel PT的简单而全栈实现。 它由内核驱动程序(用于与Intel PT硬件块通信),收集数据的命令,显示功能或指令跟踪的命令以及转储原始跟踪的命令组成。 它使用前面提到的libipt来解码数据包流。 要与Intel PT硬件块通信,它会加载内核模块(.ko)。它可以作为为Intel PT编写低级接口的资源。

4.5 AutoFDO

自动反馈定向优化器(AutoFDO)可用于根据采样配置文件驱动反馈定向编译器优化。 这允许编译器针对二进制的特定用例进行优化。 GCC和LLVM都可以使用Intel PT的perf采集的样本(由AutoFDO工具转换)。 请注意,应用程序无需提供满载,即使是小而有代表性的负载也足以收集有价值的信息。 谷歌已开始在其系统上部署AutoFDO,到2016年,超过一半的CPU周期现在用于反馈定向优化二进制文件。 Google的个人资料收集器以随机顺序抓取计算机并请求10秒的系统范围配置文件。 这相当于每天大约10%的机器,因此大约0.001%的可观察周期被分析。 在分析期间,观察到的开销不到1%。