JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris Studio 12.3:性能分析器     Oracle Solaris Studio 12.3 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

1.  性能分析器概述

2.  性能数据

3.  收集性能数据

4.  性能分析器工具

5.  er_print 命令行性能分析工具

6.  了解性能分析器及其数据

数据收集的工作原理

实验格式

archives 目录

子实验

动态函数

Java 实验

记录实验

collect 实验

创建进程的 dbx 实验

正在运行的进程上的 dbx 实验

解释性能度量

基于时钟的分析

计时度量的准确性

计时度量的比较

硬件计数器溢出分析

数据空间分析和内存空间分析

同步等待跟踪

堆跟踪

MPI 跟踪

调用堆栈和程序执行

单线程执行和函数调用

共享对象之间的函数调用

信号

陷阱

尾部调用优化

显式多线程

基于 Java 技术的软件执行概述

Java 调用堆栈和机器调用堆栈

基于时钟的分析和硬件计数器溢出分析

Java 分析视图模式

Java 分析数据的用户视图模式

Java 分析数据的专家视图模式

Java 分析数据的计算机视图模式

OpenMP 软件执行概述

OpenMP 分析数据的用户视图模式

人工函数

用户模式调用堆栈

OpenMP 度量

OpenMP 分析数据的专家视图模式

OpenMP 分析数据的计算机视图模式

不完全的堆栈展开

中间文件

将地址映射到程序结构

进程映像

装入对象和函数

有别名的函数

非唯一函数名称

来自剥离共享库的静态函数

Fortran 备用入口点

克隆函数

内联函数

编译器生成的主体函数

外联函数

动态编译的函数

<Unknown> 函数

OpenMP 特殊函数

<JVM-System> 函数

<no Java callstack recorded> 函数

<Truncated-stack> 函数

<Total> 函数

与硬件计数器溢出分析相关的函数

将性能数据映射到索引对象

将数据地址映射到程序数据对象

数据对象描述符

<Total> 数据对象

<Scalars> 数据对象

<Unknown> 数据对象及其元素

将性能数据映射到内存对象

7.  了解带注释的源代码和反汇编数据

8.  操作实验

9.  内核分析

索引

解释性能度量

每个事件的数据都包含高精度时间戳、线程 ID 和 CPU ID。这些项可用于在性能分析器中按时间、线程或 CPU 过滤度量。有关 CPU ID 的信息,请参见 getcpuid(2) 手册页。在 getcpuid 不可用的系统上,处理器 ID 为 -1(它映射为“未知”)。

除了通用数据外,每个事件还生成特定的原始数据,将在以下各节中对此进行描述。每节还将介绍从原始数据派生的度量的准确性,以及数据收集对度量的影响。

基于时钟的分析

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

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

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

表 6-1 内核微状态如何服务于度量

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

计时度量的准确性

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

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

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

计时度量的比较

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

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

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

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

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

硬件计数器溢出分析

硬件计数器溢出分析数据包括计数器 ID 和溢出值。该值可能大于计数器的溢出设置值,因为处理器在事件的溢出和记录之间会执行某些指令。尤其对循环和指令计数器来说,该值可能会更大,这些计数器的递增频率比诸如浮点运算或高速缓存未命中次数的计数器更快。记录事件中的延迟还意味着,通过调用堆栈记录的程序计数器地址并不精确对应于溢出事件。有关更多信息,请参见硬件计数器溢出的归属。另请参见陷阱的讨论。陷阱和陷阱处理程序可以导致报告的用户 CPU 时间和循环计数器报告的时间有很大差别。

动态更改其操作时钟频率的计算机上所记录的实验在基于周期的时间计数转换时显示不准确性。

收集的数据量取决于溢出值。选择过小的值可能会产生以下结果。

数据空间分析和内存空间分析

数据空间分析是对用于内存引用的硬件计数器分析的扩展。硬件计数器分析可以归属到用户函数、源代码行和指令的度量,但不归属到正在引用的数据对象的度量。缺省情况下,该收集器仅捕获用户指令地址。启用数据空间分析时,该收集器还捕获数据地址。回溯是一些计算机上使用的用于获取支持数据空间分析的性能信息的技术。启用回溯时,收集器回顾在硬件计数器事件发生之前执行的装入或存储指令,以查找可导致该事件的候选指令。在一些系统上,计数器是精确的,无需回溯。在 collect -h 命令的输出中,此类计数器用字 precise 表示。

数据空间分析是一个数据集合,它将针对导致事件的数据对象引用而非仅针对发生内存事件的指令报告内存相关事件(例如高速缓存未命中次数)。

内存空间分析与数据空间分析类似,但在内存空间分析中,针对内存子系统的组件(例如高速缓存行或页面)而非针对程序中的数据对象报告事件。当在与内存有关的精确计数器上前置 + 号时,将发生内存空间分析。

要允许进行数据空间分析,目标必须是使用 -xhwcprof 标志和 -xdebugformat=dwarf -g 标志为 SPARC 体系结构编译的 C、C++ 或 Fortran 程序。此外,收集的数据必须是与内存相关的计数器的硬件计数器分析数据,且必须在计数器名称上前置 + 号。如果在一个(非全部)与内存相关的计数器上前置了可选 +,不带 + 的计数器将针对 <<Unknown> 数据对象报告数据空间数据,其子类型为Dataspace data not requested during data collection

在具有精确中断的计算机上,不需要回溯,内存空间分析不需要用于编译的 -xhwcprof 标志和 -xdebugformat=dwarf -g 标志。数据空间分析(即使在此类计算机上)不需要标志。

当实验包含数据空间或内存空间分析时,er_print 实用程序允许执行三条附加命令:data_objectsdata_singledata_layout 以及与内存对象相关的各种命令。有关更多信息,请参见控制硬件计数器数据空间和内存对象列表的命令

此外,性能分析器包括两个与数据空间分析相关的标签(即“数据对象”标签和“数据布局”标签),以及用于内存对象的各种标签。请参见`DataObjects`(数据对象)标签`DataLayout`(数据布局)标签`MemoryObjects`(内存对象)标签

运行不带其他参数的 collect -h 将列出硬件计数器,并指明这些计数器是否与装入、存储或装入存储相关以及它们是否精确。请参见硬件计数器溢出分析数据

同步等待跟踪

收集器通过跟踪对线程库 libthread.so 中函数的调用或对实时扩展库 librt.so 的调用来收集同步延迟事件。事件特定的数据由请求和授权的高精度时间戳(跟踪的调用的开始和结束)以及同步对象(例如,请求的互斥锁)的地址组成。线程 ID 和 LWP ID 是记录数据时的 ID。等待时间是请求时间和授权时间之间的差值。仅记录其等待时间超过指定阈值的事件。同步等待跟踪数据在授权时记录在实验中。

等待线程不能执行任何其他工作,直到导致延迟的事件完成为止。等待所用时间同时显示为同步等待时间和用户锁定时间。用户锁定时间可能比同步等待时间长,因为同步延迟阈值筛去了短期延迟。

数据收集的开销使等待时间失真。该开销与收集的事件数成比例。通过增加用于记录事件的阈值,可以最大限度地减少开销中所用的等待时间部分。

堆跟踪

收集器通过插入内存分配和解除分配函数 mallocreallocmemalignfree 来记录对这些函数的调用的跟踪数据。如果程序分配内存时忽视这些函数,则不记录跟踪数据。不记录 Java 内存管理(它使用不同的机制)的跟踪数据。

跟踪的函数可能从许多库中的任一个库装入。在性能分析器中看到的数据可能取决于从其装入给定函数的库。

如果程序在很短的时间段内发出对被跟踪函数的大量调用,则执行程序所用的时间可能会大大延长。额外的时间将用于记录跟踪数据。

MPI 跟踪

MPI 跟踪基于修改的 VampirTrace 数据收集器。有关更多信息,请参见 Technische Universität Dresden Web 站点上的 VampirTrace 用户手册。