Oracle® Solaris Studio 12.4:性能分析器

退出打印视图

更新时间: 2015 年 1 月
 
 

时钟分析

时钟分析的事件特定数据由分析间隔计数的数组组成。 在 Oracle Solaris 上,提供了间隔计数器。在分析间隔结束时,相应的间隔计数器加 1,并安排另一个分析信号。仅当 Solaris 线程进入 CPU 用户模式时,才记录和重置数组。重置数组包括将用户 CPU 状态的数组元素设置为 1,将所有其他状态的数组元素设置为 0。在重置数组之前,进入用户模式时会记录数组数据。因此,该数组包含自上次进入用户模式以来进入的每个微状态的计数累积(内核为每个 Solaris 线程维护十个微状态)。在 Linux 操作系统上,不存在微状态;唯一的间隔计数器是用户 CPU 时间。

在记录数据的同时记录调用堆栈。如果在分析间隔结束时 Solaris 线程未处于用户模式,则在线程再次进入用户模式之前调用堆栈无法更改。因此,调用堆栈总是会在每个分析间隔结束时准确记录程序计数器的位置。

Oracle Solaris 上每个微状态提供的度量显示在 Table 6–1 中。

表 6-1  内核微状态如何影响度量
内核微状态
说明
度量名称
LMS_USER
在用户模式下运行
User CPU Time(用户 CPU 时间)
LMS_SYSTEM
在系统调用或缺页时运行
System CPU Time(系统 CPU 时间)
LMS_TRAP
在出现任何其他陷阱时运行
System CPU Time(系统 CPU 时间)
LMS_TFAULT
在用户文本缺页时休眠
Text Page Fault Time(文本缺页时间)
LMS_DFAULT
在用户数据缺页时休眠
Data Page Fault Time(数据缺页时间)
LMS_KFAULT
在内核缺页时休眠
Other Wait Time(其他等待时间)
LMS_USER_LOCK
等待用户模式锁定时休眠
User Lock Time(用户锁定时间)
LMS_SLEEP
由于任何其他原因而休眠
Other Wait Time(其他等待时间)
LMS_STOPPED
已停止(/proc、作业控制或 lwp_stop
Other Wait Time(其他等待时间)
LMS_WAIT_CPU
等待 CPU
Wait CPU Time(等待 CPU 时间)

计时度量的准确性

计时数据是基于统计收集的,因此易于出现任何统计抽样方法的所有误差。对于时间非常短的运行(仅记录少量分析数据包),调用堆栈可能不能表示程序中使用大多数资源的各部分。因此应以足够长的时间或足够多的次数运行程序,以累积感兴趣的函数或源代码行的数百个分析数据包。

除了统计抽样误差外,收集和归属数据的方式以及程序在系统中前进方式也会引起特定的误差。以下是计时度量可能出现不准确或失真的一些情况:

  • 创建线程时,记录第一个分析数据包之前所用的时间少于分析间隔,但是整个分析间隔取决于第一个分析数据包中记录的微状态。如果创建了许多线程,则误差可能是分析间隔的许多倍。

  • 销毁线程时,在记录最后一个分析数据包后会消耗一些时间。如果销毁了许多线程,则误差可能是分析间隔的许多倍。

  • 在分析间隔期间可能发生线程的重新调度。因此,记录的线程状态可能不能表示消耗大部分分析间隔的微状态。如果要运行的线程多于要运行它们的处理器,则误差很可能更大。

  • 程序可以与系统时钟相关联的方式运行。 在这种情况下,如果线程处于可能表示所用的一小部分时间的状态,而为特定程序部分记录的调用堆栈被过度表示,则分析间隔始终会过期。在多处理器系统上,分析信号可以引入相关性:记录微状态时,在运行程序的线程时由分析信号中断的处理器很可能处于陷阱 CPU 微状态。

  • 分析间隔过期时,内核记录微状态值。如果系统负载过重,则该值可能无法表示进程的真实状态。在 Oracle Solaris 上,此情况很可能会导致对陷阱 CPU 或等待 CPU 微状态的过多记帐。

  • 系统时钟与外部源同步时,在分析数据包中记录的时间戳不反映分析间隔,但包括对时钟进行的任何调整。时钟调整可能使分析数据包看起来已丢失。涉及的时间段通常为几秒,并且调整是以增量方式进行的。

  • 在动态更改其操作时钟频率的计算机上所记录的实验可能在分析中显示不准确之处。

除刚刚介绍的不准确之处外,计时度量还会因收集数据的过程而失真。 记录分析数据包所用的时间从不出现在程序的度量中,因为记录是由分析信号启动的。(这是相关性的另一个实例。记录过程中所用的用户 CPU 时间在所记录的任何微状态之间分配。结果是对用户 CPU 时间度量过少记帐,而对其他度量过多记帐。记录数据所用的时间量通常不到缺省分析间隔的 CPU 时间的百分之几。

计时度量的比较

如果将通过在基于时钟的实验中进行分析所获得的计时度量与通过其他方式获得的时间进行比较,则应该注意以下问题。

对于单线程应用程序,为进程记录的总线程时间通常精确到千分之几(与同一进程的 gethrtime(3C) 返回的值相比)。 CPU 时间可能与由同一进程的 gethrvtime(3C) 返回的值相差几个百分点。如果负载过重,则差异可能更加明显。但是,CPU 时间差异并不表示系统失真,为不同函数、源代码行等报告的相对时间不会显著失真。

性能分析器中报告的线程时间可能与 vmstat 报告的时间有很大差异,因为 vmstat 报告的是各 CPU 的线程时间总和。如果目标进程具有的 LWP 比它所运行的系统具有的 CPU 多,则性能分析器显示的等待时间比 vmstat 报告的长。

出现在性能分析器的 "Statistics"(统计信息)视图和 er_print 统计信息显示中的微状态计时基于进程文件系统 /proc 使用报告,因此微状态中所用时间的记录具有很高的准确性。有关更多信息,请参见 proc (4) 手册页。可以将这些计时与 <Total> 函数(它将程序作为一个整体表示)的度量进行比较,以获取聚集计时度量的准确性指示。 但是,"Statistics"(统计信息)视图中显示的值可能包含其他基值,而 <Total> 的计时度量值中不包含这些基值。这些基值来自暂停数据收集的时间段。

用户 CPU 时间和硬件计数器循环时间是不同的,因为在将 CPU 模式切换到系统模式时会关闭硬件计数器。有关更多信息,请参见陷阱