Oracle Solaris Studio 12.2:性能分析器

硬件计数器溢出分析数据

硬件计数器可跟踪诸如高速缓存未命中次数、高速缓存停止周期、浮点运算、分支误预测、CPU 周期以及执行指令之类的事件。在硬件计数器溢出分析中,当运行 LWP 的 CPU 的指定硬件计数器溢出时,收集器会记录分析数据包。计数器将重置并继续进行计数。分析数据包中包括溢出值和计数器类型。

各种 CPU 系列支持同时存在二到十八个硬件计数器寄存器。收集器可收集一个或多个寄存器上的数据。对于每个寄存器,收集器都允许您选择计数器的类型来监视溢出,并设置计数器的溢出值。有些硬件计数器可以使用任意寄存器,而有些计数器仅可以使用特定的寄存器。因此,在一个实验中并非可以选择所有的硬件计数器组合。

硬件计数器溢出分析数据由性能分析器转换为计数度量。对于以循环方式计数的计数器,所报告的度量会转换为次数;而对于不以循环方式计数的计数器,所报告的度量为事件计数。在具有多个 CPU 的计算机上,用于转换度量的时钟频率为各个 CPU 时钟频率的调和平均数。因为每种类型的处理器都有其自己的一组硬件计数器,并且硬件计数器的数目庞大,因此,此处未列出硬件计数器的度量。下一小节讲述如何找出可用的硬件计数器。

硬件计数器的一个用途是可诊断进出 CPU 的信息流问题。例如,高速缓存未命中次数计数较高表明,重新组织程序的结构来改进数据或文本的位置或提高高速缓存的重用率可以改善程序性能。

某些硬件计数器与其他计数器相互关联。例如,分支误预测和指令高速缓存未命中次数通常是相关的,因为分支误预测会导致将错误的指令装入到指令高速缓存,而这些指令必须替换为正确的指令。这种替换会导致指令高速缓存未命中,或指令转换后备缓冲器 (instruction translation lookaside buffer, ITLB) 未命中,或甚至缺页。

通常会在导致事件和相应事件计数器溢出的指令之后,向硬件计数器溢出传送一条或多条指令:这称为“失控 (skid)”,它会使计数器溢出分析数据难以解释。如果缺少对精确识别因果指令的硬件支持,可以对候选的因果指令尝试合适的回溯搜索。

收集期间支持和指定这种回溯时,硬件计数器分析数据包还包括适用于硬件计数器事件的候选内存引用指令的 PC(program counter,程序计数器)和 EA(effective address,有效地址)。(在分析期间需要进行后续处理来验证候选事件 PC 和 EA)。关于内存引用事件的这一附加信息为各种面向数据的分析(又称为数据空间分析)提供了方便。仅在运行 Oracle Solaris 操作系统的基于 SPARC 的平台上支持回溯。

也可以为时钟分析指定候选事件 PC 和 EA 的回溯和记录,尽管这可能难以解释。

硬件计数器列表

由于硬件计数器是特定于处理器的,因此可以选用的计数器取决于所使用的处理器。性能工具为许多可能常用的计数器提供了别名。通过在特定系统上的终端窗口中键入不带任何参数的 collect,您可从收集器获得该系统上可用的硬件计数器列表。如果处理器和系统支持硬件计数器分析,则 collect 命令会列显两个包含有关硬件计数器信息的列表。第一个列表包含别名为通用名称的硬件计数器;第二个列表包含原始硬件计数器。如果性能计数器子系统和 collect 命令都不知道特定系统上的计数器名称,这些列表将为空。但是,在大多数情况下,可以用数值指定计数器。

以下示例显示了计数器列表中的条目。有别名的计数器将首先显示在列表中,然后是原始硬件计数器列表。该示例中的每一行输出都按打印格式显示。


Aliased HW counters available for profiling:
cycles[/{0|1}],9999991 (’CPU Cycles’, alias for Cycle_cnt; CPU-cycles)
insts[/{0|1}],9999991 (’Instructions Executed’, alias for Instr_cnt; events)
dcrm[/1],100003 (’D$ Read Misses’, alias for DC_rd_miss; load events)
...
Raw HW counters available for profiling:
Cycle_cnt[/{0|1}],1000003 (CPU-cycles)
Instr_cnt[/{0|1}],1000003 (events)
DC_rd[/0],1000003 (load events)

有别名的硬件计数器列表的格式

在有别名的硬件计数器列表中,第一个字段(例如,cycles)提供可以在 collect 命令的 -h counter... 参数中使用的别名。此别名还是在 er_print 命令中使用的标识符。

第二个字段列出计数器的可用寄存器,例如 [/{0|1}]

第三个字段(例如 9999991)是计数器的缺省溢出值。对于有别名的计数器,选择的缺省值可提供合理的样本率。由于实际样本率变化相当大,因此可能需要指定缺省值以外的值。

第四个字段(在圆括号中)包含类型信息。它提供简短描述(例如 CPU Cycles)、原始硬件计数器名称(例如 Cycle_cnt)以及计数单位类型(例如 CPU-cycles)。

如果类型信息的第一个单词是:

如果类型信息的第二个单词或仅有的单词是:

在示例中的有别名的硬件计数器列表中,类型信息包含一个单词的,如第一个计数器的 CPU-cycles 和第二个计数器的 events。类型信息包括两个单词的,如第三个计数器的 load events

原始硬件计数器列表的格式

原始硬件计数器列表中包含的信息是有别名的硬件计数器列表中信息的子集。原始硬件计数器列表中的每行包括由 cpu-track(1) 使用的内部计数器名称、可以在其上使用计数器的寄存器编号、缺省溢出值和计数器单位(可以是 CPU-cyclesEvents)。

如果计数器度量与运行的程序无关的事件,则类型信息的第一个单词是 not-program-related。对于这样的计数器,分析不会记录调用栈,而是显示人工函数 collector_not_program_related 中所用的时间。线程和 LWP ID 会被记录,但没有任何意义。

原始计数器的缺省溢出值为 1000003。对于大多数原始计数器来说,此值并非理想值,所以您应在指定原始计数器时指定溢出值。