所有实验都必须具有以下三个文件:
日志文件 (log.xml),它是一个 XML 文件,包含有关所收集数据、各种组件的版本、目标生存期内各种事件的记录和目标字大小的信息。
映射文件 (map.xml),它是一个 XML 文件,记录有关将哪些装入对象装入目标的地址空间以及装入或卸载它们的时间的时间相关信息。
概述文件,它是一个二进制文件,包含在实验中的每个抽样点记录的用法信息。
此外,实验还具有表示整个处理过程中的分析事件的二进制数据文件。每个数据文件都具有一系列事件,如下面解释性能度量所述。对于每种类型的数据,都将使用单独的文件,但每个文件都由目标中的所有 LWP 共享。数据文件的命名如下:
表 7–1 数据类型和对应的文件名
数据类型 |
文件名 |
---|---|
基于时钟的分析 |
profile |
硬件计数器溢出分析 |
hwcounters |
同步跟踪 |
synctrace |
堆跟踪 |
heaptrace |
MPI 跟踪 |
mpitrace |
开放式 MP 跟踪 |
omptrace |
对于基于时钟的分析或硬件计数器溢出分析,将数据写入时钟周期或计数器溢出调用的信号处理程序中。对于同步跟踪、堆跟踪、MPI 跟踪或开放式 MP 跟踪,从 LD_PRELOAD 环境变量在用户调用的常规例程上插入的 libcollector.so 例程写入数据。每个这样的插入例程都部分填充数据记录,然后调用用户调用的常规例程,在该例程返回时填充数据记录的其余部分,并将记录写入数据文件。
所有数据文件都按块进行内存映射和写入。以这样的方式填充记录以便始终具有有效的记录结构,这样就可以在写入时读取实验。缓冲区管理策略设计用于最大限度地减少 LWP 之间的争用和序列化。
实验可以选择性地包含文件名为 notes 的 ASCII 文件。使用 collect 命令的 -C comment 参数时会自动创建此文件。创建实验后,可以手动创建或编辑该文件。该文件的内容会置于实验标题之前。
每个实验都具有 archives 目录,该目录包含描述 map.xml 文件中引用的每个装入对象的二进制文件。这些文件由 er_archive 实用程序(它在数据收集结束时运行)生成。如果进程异常终止,则可能无法调用 er_archive 实用程序,在这种情况下,归档文件由 er_print 实用程序或分析器在实验上首次调用时写入。
后续进程将其实验写入创始进程的实验目录内的子目录。
对这些新实验的命名可指示其衍生情况,如下所示:
将下划线附加到创建者的实验名称
添加以下代码字母之一:f 代表派生,x 代表执行,c 代表其他后续进程。
在代码字母后添加一个表示派生或执行的索引的数字。不管是否成功启动了进程,都会应用此数字。
附加实验后缀 .er 以构成完整的实验名称。
例如,如果创始进程的实验名称为 test.1.er,则由其第三个派生创建的子进程的实验为 test.1.er/_f3.er。如果该子进程执行新映像,则对应的实验名称为 test.1.er/_f3_x1.er。后续实验由与父实验相同的文件组成,但是它们没有后续实验(所有后续实验都由创始实验中的子目录表示),而且它们没有归档子目录(所有归档都在创始实验中进行)。
目标创建动态函数的实验在 map.xml 文件中具有描述这些函数的附加记录,还具有一个附加文件 dyntext,该文件包含动态函数的实际指令的副本。生成动态函数的带注释反汇编时需要该副本。
Java 实验在 map.xml 文件中具有附加记录,这两个记录用于 JVM 软件因其内部目的而创建的动态函数和目标 Java 方法的动态编译 (HotSpot) 版本。
此外,Java 实验具有一个 JAVA_CLASSES 文件,该文件包含有关调用的所有用户 Java 类的信息。
使用 JVMTI 代理记录 Java 跟踪数据,该代理是 libcollector.so 的一部分。该代理接收映射到记录的跟踪事件中的事件。该代理还接收类装入和 HotSpot 编译(用于写入 JAVA_CLASSES 文件)的事件以及 map.xml 文件中 Java 编译的方法记录。