Sun Studio 12:性能分析器

第 3 章 收集性能数据

性能分析的第一个阶段是数据收集。本章介绍了进行数据收集的要求、数据的存储位置、如何收集数据以及如何管理数据收集。有关数据本身的更多信息,请参见第 2 章,性能数据

本章包含以下主题。

编译和链接程序

几乎可以为使用任何选项编译的程序收集和分析数据,但有些选项会影响能够在性能分析器中收集或查看的内容。以下几个小节介绍了在编译和链接程序时应考虑的问题。

源代码信息

查看带注释的“源代码”和“反汇编”分析中的源代码以及“行”分析中的源代码行,就必须使用 -g 编译器选项(对于 C++ 来说为用于启用前端内联的 -g0)编译感兴趣的源文件,以生成调试符号信息。调试符号信息的格式可以是 DWARF2 或 stabs,由 -xdebugformat=(dwarf|stabs) 指定。缺省的调试格式是 dwarf

要使用允许使用数据空间分析的调试信息准备编译对象(当前仅适用于 SPARC® 处理器),请通过指定 -xhwcprof -xdebugformat=dwarf 和任何级别的优化来进行编译。(目前,这种功能在未经过优化的情况下无法使用。)要查看“数据对象”分析中的程序数据对象,也要添加 -g(对于 C++ 来说为 -g0)以获取全部符号信息。

用 DWARF 格式的调试符号生成的可执行文件和库会自动包括每个要素目标文件调试符号的副本。如果用 stabs 格式的调试符号生成的可执行文件和库与 -xs 选项(该选项将 stabs 符号保留在各个目标文件及可执行文件中)相链接,那么所生成的可执行文件和库中也会包括每个要素目标文件的调试符号。当您需要移动或删除目标文件时,包括这些信息尤为重要。使用可执行文件和库本身中的所有调试符号,可以更容易地将实验和与程序相关的文件移至新位置。

静态链接

编译程序时,必须使用 -dn-Bstatic 编译器选项打开动态链接。如果试图收集完全静态链接的程序的数据,则收集器会列显一条错误消息并且不收集数据。出现此错误的原因在于,当您运行收集器时,该收集器库也会像其他库一样动态装入。

请不要静态链接任何系统库。如果您执行了静态链接,则可能无法收集任何种类的跟踪数据。另外,请不要链接到收集器库 libcollector.so

编译时优化

如果使用在某一级别打开的优化来编译程序,编译器就可以重新安排执行顺序,这样就无须严格按照程序中行的顺序来执行程序。性能分析器可以分析在优化后的代码中收集的实验,但它在反汇编级别所显示的数据通常很难与初始源代码行相关联。此外,如果编译器执行尾部调用优化,则调用序列可能与预期的序列不同。有关更多信息,请参见尾部调用优化

编译 Java 程序

javac 命令编译 Java 程序无需任何特殊操作。

为数据收集和分析准备程序

对于大多数程序来说,您不必为数据收集和分析做任何特殊的准备。如果程序执行下列任一操作,则应当阅读下面的一个或多个小节:

此外,如果要控制程序中的数据收集,还应当阅读相关小节。

使用动态分配的内存

许多程序依赖于动态分配的内存,它们使用诸如以下各项的功能:

必须小心确保程序不依赖于动态分配的内存的初始内容,除非内存分配方法明确地说明要设置初始值:例如,比较 malloc(3C) 手册页中对 callocmalloc 的描述。

偶尔,使用动态分配的内存的程序似乎可以单独地正常运行,但是启用性能数据收集之后就会失败。症状可能包括意外的浮点行为、段故障或特定于应用程序的错误消息。

如果应用程序单独运行时未初始化的内存偶然设置为良性值,但应用程序与性能数据收集工具一起运行时未初始化的内存被设置为其他值,则会出现这种行为。发生这种情况时,问题不出在性能工具上。依赖于动态分配的内存内容的任何应用程序都具有潜在的错误:除非明确说明使用其他方法,否则操作系统将为动态分配的内存随机提供任意内容。即使目前操作系统会始终将动态分配的内存设置为某个值,但是将来在使用操作系统的后续修订版或将程序移植到其他操作系统时,这些潜在的错误会引起意外的行为。

下列工具可以帮助您找到这些潜在的错误:

使用系统库

收集器插入各种系统库的函数,以收集跟踪数据并确保数据收集的完整性。下面的列表描述了收集器插入库函数调用的情况。

在某些情况下,插入不会成功:

收集器插入失败可能会导致性能数据丢失或无效。

使用信号处理程序

收集器使用以下两个信号来收集分析数据:SIGPROF(所有实验)和 SIGEMT(仅限硬件计数器实验)。收集器为其中的每个信号安装一个信号处理程序。该信号处理程序截获并处理它自己的信号,但是会将其他信号传递到所安装的其他信号处理程序。如果程序为这些信号安装其自己的信号处理程序,则收集器会将其信号处理程序作为主处理程序重新安装,以保证性能数据的完整性。

collect 命令还可以将用户指定的信号用于暂停和恢复数据收集以及记录样本。尽管在安装用户处理程序时向实验中写入警告,但这些信号不受收集器保护。确保收集器对指定信号的使用与应用程序对相同信号的使用之间没有冲突是您的责任。

由收集器安装的信号处理程序会设置一个确保系统调用不被信号传送中断的标志。如果程序的信号处理程序将该标志设置为允许中断系统调用,则设置该标志可以更改程序的行为。在异步 I/O 库 libaio.so 中就有一个行为更改的重要示例,它将 SIGPROF 用于异步取消操作,并且中断系统调用。如果已安装收集器库 libcollector.so则取消信号总是来得太迟,以至于无法取消异步 I/O 操作。

如果在未预装入收集器库和启用性能数据收集的情况下将 dbx 附加到进程,并且程序随后安装其自身的信号处理程序,则收集器不再重新安装其自身的信号处理程序。在这种情况下,程序的信号处理程序必须确保 SIGPROFSIGEMT 信号被传递,以便性能数据不丢失。如果程序的信号处理程序中断系统调用,那么程序行为和分析行为都将与预装入收集器库时不同。

使用 setuid

由于动态装入器实施了一定的限制,因此将难以使用 setuid(2) 和收集性能数据。如果您的程序调用 setuid或执行 setuid 文件,则收集器可能无法写入实验文件,原因是它缺少新用户 ID 的必需权限。

此问题可以通过以下方法来解决:确保 umask 的设置可将写入权限授予进程在运行时所使用的任何 UID 或 GID。针对实验,这些 ID 必须具有写入权限。

数据收集的程序控制

如果要控制程序中的数据收集,收集器共享库 libcollector.so 包含了一些可以使用的 API 函数。这些函数是用 C 编写的,还提供了一个 Fortran 接口。C 接口和 Fortran 接口都是在由库所提供的头文件中定义的。

API 函数定义如下所示。


void collector_sample(char *name);
void collector_pause(void);
void collector_resume(void);
void collector_thread_pause(unsigned int t);
void collector_thread_resume(unsigned int t);
void collector_terminate_expt(void);

CollectorAPI 类为 JavaTM 程序提供了类似的功能,Java 接口中对其进行了介绍。

C 和 C++ 接口

可通过两种方法来访问 C 和 C++ 接口:

Fortran 接口

Fortran API libfcollector.h 文件定义了库的 Fortran 接口。要使用该库,必须使用 -lcollectorAPI 链接应用程序。(还提供了该库的替代名称 -lfcollector,目的在于实现向后兼容性。)除动态函数、线程暂停和恢复调用等功能外,Fortran API 提供了与 C 和 C++ API 相同的功能。

要使用 Fortran 的 API 函数,请插入下面的语句:


include "libfcollector.h"

注 –

请勿使用 -lcollector 链接任何语言的程序,否则,收集器可能会出现不可预知的行为。


Java 接口

使用以下语句导入 CollectorAPI 类并访问 Java API。但是请注意,必须使用指向 / installation_directory/lib/collector.jar 的类路径来调用应用程序,其中 installation-directory 是 Sun Studio 软件的安装目录。


import com.sun.forte.st.collector.CollectorAPI;

Java CollectorAPI 方法的定义如下所示:


CollectorAPI.sample(String name)
CollectorAPI.pause()
CollectorAPI.resume()
CollectorAPI.threadPause(Thread thread)
CollectorAPI.threadResume(Thread thread)
CollectorAPI.terminate()

除动态函数 API 之外,Java API 包含与 C 和 C++ API 相同的函数。

C 头文件 libcollector.h 包含一些宏,这些宏的作用是如果当时未在收集数据,则跳过对真正的 API 函数的调用。在这种情况下,不动态装入函数。但是,由于在某些情况下这些宏不能很好地运行,所以使用这些宏会有风险。使用 collectorAPI.h 较为安全,因为它不使用宏,而是直接引用函数。

如果正在收集性能数据,则 Fortran API 子例程会调用 C API 函数,否则这些子例程将返回。检查的开销很低,不会对程序性能产生太大的影响。

如本章稍后所述,要收集性能数据就必须使用收集器运行您的程序。插入对 API 函数的调用不会启用数据收集功能。

如果要在多线程程序中使用 API 函数,应当确保它们只由一个线程调用。除 collector_thread_pause()collector_thread_resume() 之外,API 函数执行适用于进程(而不是单独的线程)的操作。如果每个线程都调用 API 函数,则记录的数据可能会与预期不同。例如,如果一个线程在其他线程到达程序中的同一点之前调用了 collector_pause()collector_terminate_expt(),则会针对所有线程暂停或终止收集,从而丢失那些正在执行 API 调用之前代码的线程的数据。要在单独的线程级别控制数据收集,请使用 collector_thread_pause()collector_thread_resume() 函数。可通过两种方法来使用这些函数:一种是使用一个主线程为所有线程(包括其自身)执行调用;另一种是让每个线程只执行它自己的调用。其他任何用法都可能产生不可预知的结果。

C、C++、Fortran 和 Java API 函数

对 API 函数的描述如下所示。

动态函数和模块

如果 C 或 C++ 程序向程序的数据空间动态编译函数,而且您希望在性能分析器中查看动态函数或模块的数据,那么,您必须向收集器提供信息。该信息由对收集器 API 函数的调用传递。API 函数的定义如下所示。


void collector_func_load(char *name, char *alias,
    char *sourcename, void *vaddr, int size, int lntsize,
    Lineno *lntable);
void collector_func_unload(void *vaddr);

您不必将这些 API 函数用于由 Java HotSpotTM 虚拟机编译的 Java 方法,该虚拟机使用的是另一个接口。Java 接口提供已编译到收集器的方法的名称。您可以查看 Java 编译方法的函数数据和带注释的反汇编列表,但不能查看带注释的源代码列表。

对 API 函数的描述如下所示。

collector_func_load()

将有关动态编译的函数的信息传递到收集器,以便在实验中进行记录。下表对参数列表进行了描述。

表 3–1 collector_func_load() 的参数列表

参数 

定义 

name

性能工具所使用的动态编译函数的名称。该名称不必是函数的实际名称。虽然该名称不应包含嵌入的空格或引号字符,但无须遵循通常的函数命名约定。 

alias

用于描述函数的任意字符串。它可以是 NULL。它不经过任何方式的解释,可以包含嵌入的空格。它显示在分析器的“摘要”选项卡中。它可用于指示函数的内容或动态构造函数的原因。

sourcename

构造函数时所在源文件的路径。它可以是 NULL。该源文件用于带注释的源代码列表。

vaddr

函数的装入地址。 

size

以字节为单位的函数大小。 

lntsize

对行号表中条目数量的计数。如果未提供行号信息,则计数应为零。 

lntable

包含 lntsize 条目的表,其中每个条目都是一对整数。第一个整数是偏移量,第二个整数是行号。在一个条目的偏移量和下一个条目中所给出的偏移量之间的所有指令都归属于在第一个条目中提供的行号。偏移量必须按数字升序列出,但行号的顺序可以是任意的。如果 lntableNULL,则没有可用的函数源代码列表,不过反汇编列表是可用的。

collector_func_unload()

通知收集器位于地址 vaddr 的动态函数已卸载。

数据收集的限制

本节描述了数据收集的限制,这些限制是由硬件、操作系统、程序的运行方式或收集器本身造成的。

对同时收集不同类型的数据来说,没有任何限制:您可以在收集某种数据类型的同时收集任何其他数据类型。

基于时钟的分析的限制

用于分析的分析间隔最小值和时钟精度取决于特定的操作环境。最大值设置为 1 秒。分析间隔值将向下舍入到最接近的时钟精度的整数倍。可以通过键入不带参数的 collect 命令来查找最小值和最大值以及时钟精度。

时钟分析中的运行时失真和扩大

基于时钟的分析记录当 SIGPROF 信号传递到目标时的数据。这将导致在处理该信号和展开调用栈时产生扩大。调用栈越深,信号越频繁,扩大越显著。在一定程度上,基于时钟的分析表现出一些失真,这是由程序中那些执行最深栈部分的显著扩大而导致的。

请尽可能不要将缺省值设置为一个精确的毫秒数,而是将其设置为稍大于或稍小于某个精确数(例如,10.007 毫秒或 0.997 毫秒),以免与系统时钟关联,从而避免数据失真。在 SPARC 平台上,可以按照同样的方式来设置定制值(在 Linux 平台上不能设置定制值)。

收集跟踪数据的限制

只有在已预装入收集器库 libcollector.so 的情况下,才可以从已在运行的程序中收集任何种类的跟踪数据。有关更多信息,请参见从正在运行的程序中收集跟踪数据

跟踪过程中的运行时失真和扩大

跟踪数据使运行与被跟踪事件的数量成比例地扩大。如果完成了基于时钟的分析,则跟踪事件所引起的扩大将导致时钟数据失真。

硬件计数器溢出分析的限制

硬件计数器溢出分析存在多种限制:

硬件计数器溢出分析中的运行时失真和扩大

硬件计数器溢出分析功能记录当 SIGEMT 传递到目标时的数据。这将导致在处理该信号和展开调用栈时产生扩大。与基于时钟的分析不同的是,对于某些硬件计数器,程序的不同部分可能会比其他部分更快速地生成事件并显示在该部分代码中的扩大。程序中快速生成这类事件的任何部分都可能会显著失真。类似地,某些事件可能会在一个线程中与其他线程不成比例地生成。

后续进程中数据收集的限制

可以在下列限制下在后续进程中收集数据。

如果要在收集器所跟踪的所有后续进程中收集数据,就必须使用带有下列选项之一的 collect 命令:

有关 -F 选项的更多信息,请参 实验控制选项

Java 分析的限制

可以在下列限制下在 Java 程序中收集数据:

用 Java 编程语言所编写的应用程序的运行时性能失真和扩大

Java 分析功能使用的 Java 虚拟机工具接口 (Java Virtual Machine Tool Interface, JVMTI) 可能会导致运行的失真和扩大。

对于基于时钟的分析和硬件计数器溢出分析,数据收集进程会对 JVM 软件进行各种调用,并使用信号处理程序处理分析事件。这些例程的开销和将实验写入磁盘的代价将扩大 Java 程序的运行时。这种扩大通常小于 10%。

对于同步跟踪,数据收集功能使用其他 JVMTI 事件,这将导致扩大(与应用程序中监视争用数量成比例)。

数据的存储位置

应用程序的一次执行过程中所收集的数据称作实验。实验由存储在一个目录下的一组文件组成。实验的名称即目录的名称。

除记录实验数据以外,收集器还为程序所使用的装入对象创建自己的归档文件。这些归档文件包含装入对象中每个目标文件和函数的地址、大小和名称以及装入对象的地址和上次修改的时间戳。

缺省情况下,实验存储在当前目录中。如果该目录位于网络文件系统上,则存储数据所需的时间比在本地文件系统中长,而且可能会导致性能数据失真。如有可能,应始终尝试在本地文件系统中记录实验。可以在运行收集器时指定存储位置。

后续进程的实验存储在创始进程的实验内部。

实验名称

新实验的缺省名称为 test.1.er。后缀 .er 是必需的:如果您赋予的名称不具有该后缀,则系统会显示一条错误消息而且不接受该名称。

如果您选择使用格式为 experiment.n.er 的名称(其中,n 是正整数),则收集器会将后续实验名称中的 n 自动递增 1,例如,mytest.1.er 的后面是 mytest.2.ermytest.3.er 等。如果实验已经存在,收集器也会递增 n,直到找到未使用的实验名称才停止递增 n。如果实验名称不含 n 且实验存在,则收集器会列显一条错误消息。

实验可按组收集。组在实验组文件中定义,缺省情况下该文件存储在当前目录中。实验组文件是纯文本文件,它具有特殊的标题行,并在随后的每一行中显示实验名称。实验组文件的缺省名称为 test.erg如果名称不以 .erg 结尾,则系统会显示一条错误并且不接受该名称。创建实验组后,您使用该组名运行的所有实验都会添加到该组中。

可以通过创建首行为


#analyzer experiment group

的纯文本文件并将实验名称添加到后续行来手动创建实验组文件。文件的名称必须以 .erg 结尾。

还可以通过使用带有 -g 参数的 collect 命令来创建实验组。

缺省实验名称与从 MPI 程序中收集的实验名称不同,MPI 程序会为每个 MPI 进程创建一个实验。缺省实验名称为 test.m.er,其中 m 是进程的 MPI 等级。如果指定了实验组 group.erg,则缺省实验名称为 group.m.er。如果指定了实验名称,则该名称会覆盖缺省值。有关更多信息,请参见从 MPI 程序收集数据

后续进程的实验是沿袭命名的,如下所示。要形成后续进程的实验名称,可将下划线、代码字母和数字添加到其创建者实验名称的主干中。代码字母 f 表示派生,x 表示执行,c 表示组合。数字是派生或执行的索引(无论是否成功)。例如,如果创始进程的实验名称为 test.1.er,则在第三次调用 fork 时为子进程创建的实验为 test.1.er/_f3.er。如果子进程成功调用 exec,则新后续进程的实验名称为 test.1.er/_f3_x1.er

移动实验

如果要将实验移到其他计算机以便对其进行分析,则应了解分析对在其中记录实验的操作环境的依赖性。

归档文件包含计算函数级度量和显示时间线所必需的全部信息。但是,如果要查看带注释的源代码或带注释的反汇编代码,则必须能够访问与记录实验时所用装入对象或源文件相同的版本。

性能分析器在下列位置依次搜索源代码、对象和可执行文件,并在找到具有正确基本名称的文件时停止:

可以从分析器 GUI 或通过使用 setpathaddpath 指令来更改搜索顺序或添加其他搜索目录。

为了确保能够看到程序的正确的带注释源代码和带注释反汇编代码,可以在移动或复制实验之前将源代码、目标文件和可执行文件复制到该实验中。如果您不想复制目标文件,则可以使用 -xs 来链接程序,以确保源代码行和文件位置上的信息插入可执行文件中。可以通过使用 collect 命令的 -A 选项或 dbx collector archive 命令将装入对象自动复制到实验中。

估计存储要求

本节就如何对记录实验所需的磁盘空间量进行估计提供了一些指导。实验的大小直接取决于数据包的大小、记录数据包的速率、程序使用的 LWP 的数量和程序的执行时间。

数据包中包含特定于事件的数据和取决于程序结构(调用栈)的数据。取决于数据类型的数据量约为 50 到 100 个字节。调用栈数据由每个调用的返回地址组成,每个地址包含 4 个字节(在 64 位可执行文件中为 8 个字节)。记录了实验中的每个 LWP 的数据包。请注意,对于 Java 程序,有两个相关的调用栈:Java 调用栈和机器调用栈,因此将导致向磁盘中写入更多的数据。

记录分析数据包的速率由时钟数据的分析间隔和硬件计数器数据的溢出值来控制。但是,对于这些参数的选择也会因数据收集的开销而影响数据质量和程序性能的失真。这些参数的值越小,提供的统计信息越好,但开销也会越大。为了在获得较好统计信息和尽可能降低开销之间实现折衷,我们已经为分析间隔和溢出值精心选择了缺省值。值越小,数据越多。

对于一个具有 10 毫秒分析间隔和较小调用栈的基于时钟的分析实验,包的大小为 100 个字节,对于每个 LWP,记录数据的速率为 10 千字节/ 秒。对于溢出值为 1000000 以及在 750 MHz 处理器上收集有关 CPU 循环和执行指令数据的硬件计数器溢出分析实验,包的大小为 100 个字节,对于每个 LWP,记录数据的速率为 150 千字节/ 秒。调用栈深度为数百个调用的应用程序可以很轻松地以十倍的速率记录数据。

在估计实验大小时,还应当考虑归档文件所占用的磁盘空间,它通常是所要求的总磁盘空间的一小部分(请参见上一节)。如果您无法确定所需空间的大小,请尝试运行实验一小会儿。通过该测试,可以得到与数据收集时间无关的归档文件大小,然后对分析文件的大小进行放大以获得全长实验的估计大小。

除了分配磁盘空间之外,收集器还在内存中分配缓冲区,以便在将分析数据写入磁盘之前对其进行存储。目前无法指定这些缓冲区的大小。如果收集器用完了内存,请尝试减少所收集的数据量。

如果存储实验所需的估计空间大于可用空间,请考虑收集部分运行(而不是全部运行)的数据。要收集部分运行的数据,可以使用 collect 命令或 dbx collector 子命令,也可以在程序中插入对收集器 API 的调用。还可以对由 collect 命令或 dbx collector 子命令所收集的分析和跟踪数据总量进行限制。


注 –

性能分析器无法读取大于 2 GB 的性能数据。


收集数据

可以通过多种方法在独立性能分析器或 IDE 的分析器窗口中收集性能数据:

只有“性能工具收集”对话框和 collect 命令提供下列数据收集功能:

使用 collect 命令收集数据

从命令行使用 collect 命令运行收集器,请键入以下内容。


% collect collect-options program program-arguments

其中,collect-optionscollect 命令选项program 是要收集其数据的程序的名称,program-arguments 是该程序的参数。

如果未提供 collect-options,则缺省情况下会打开分析间隔大约为 10 毫秒的基于时钟的分析。

要获取可用于分析的选项列表和所有硬件计数器的名称列表,请键入不带参数的 collect 命令。


% collect

有关对硬件计数器列表的描述,请参见硬件计数器溢出分析数据。另请参见硬件计数器溢出分析的限制

数据收集选项

这些选项控制所收集数据的类型。有关对数据类型的介绍,请参见收集器收集何种数据

如果未指定数据收集选项,则缺省值为 -p on,这会启用缺省分析间隔大约为 10 毫秒的基于时钟的分析。该缺省值由 -h 选项关闭,而不是由任何其他数据收集选项关闭。

如果您明确禁用了基于时钟的分析,而且未启用跟踪或硬件计数器溢出分析,则 collect 命令会列显一条警告消息,并且只收集全局数据。

-p option

收集基于时钟的分析数据。option 的允许值包括:

collect 命令的缺省操作是收集基于时钟的分析数据。

-h counter_definition_1 ...[,counter_definition_n]

收集硬件计数器溢出分析数据。计数器定义的数量与处理器有关。如果安装了 perfctr 修补程序(可以从 http://user.it.uu.se/~mikpe/linux/perfctr/2.6/perfctr-2.6.15.tar.gz 下载),则该选项当前在运行 Linux 操作系统的系统上是可用的。

计数器定义可以采用下列形式之一,具体取决于处理器是否支持硬件计数器的属性。

[+]counter_name[/register_number][,interval]

[+]counter_name[~ attribute_1=value_1]...[~attribute_n=value_n][/register_number][,interval]

特定于处理器的 counter_name 可以为下列名称之一:

如果指定了多个计数器,则它们必须使用不同的寄存器。如果它们未使用不同的寄存器,则 collect 命令会列显一条错误消息并退出。某些计数器可在任一寄存器上计数。

要获取可用计数器的列表,请在终端窗口中键入不带参数的 collect硬件计数器列表一节提供了对计数器列表的介绍。

如果硬件计数器对其计数的事件与内存访问有关,则可以在计数器名称前添加 + 符号,以针对引起计数器溢出的指令打开对其真实程序计数器地址 (PC) 的搜索。这种回溯功能适用于 SPARC 处理器,并且仅适用于类型为 loadstoreload-store 的计数器。如果搜索成功,则所引用的虚拟 PC、物理 PC 和有效地址将存储在事件数据包中。

在某些处理器上,可以将多个属性选项与一个硬件计数器关联。如果某个处理器支持多个属性选项,则运行不带参数的 collect 命令会列出计数器定义(包括属性名)。可以使用十进制或十六进制格式来指定属性值。

间隔(溢出值)是事件计数的数量,在达到该数量时,硬件计数器将溢出并且将记录溢出事件。间隔可以设置为下列值之一:

缺省值是为每个计数器预定义的正常阈值,它出现在计数器列表中。另请参见硬件计数器溢出分析的限制

如果在使用 -h 选项时未明确指定 -p 选项,则基于时钟的分析功能将处于关闭状态。要同时收集硬件计数器数据和基于时钟的数据,必须同时指定 -h 选项和 -p 选项。

-s option

收集同步等待跟踪数据。option 的允许值包括:

不记录 Java 监视器的同步等待跟踪数据。

-H option

收集堆跟踪数据。option 的允许值包括:

缺省情况下,堆跟踪功能处于关闭状态。对于 Java 程序,不支持堆跟踪;如果指定堆跟踪,将被视为错误。

-m option

收集 MPI 跟踪数据。option 的允许值包括:

缺省情况下,MPI 跟踪功能处于关闭状态。

有关其调用被跟踪的 MPI 函数以及从跟踪数据中所计算的度量的更多信息,请参见MPI 跟踪数据

-S option

定期记录样本包。option 的允许值包括:

缺省情况下,启用间隔为 1 秒的定期抽样功能。

-c option

记录计数数据(仅用于 SPARC 处理器)。


注 –

此功能要求您安装 Binary Interface Tool (BIT),它是 Sun Studio 12(可从 http://cooltools.sunsource.net/ 获取)中一个很不错的附加工具。BIT 是用来度量 SPARC 二进制代码的性能或测试套件适用范围的工具。


option 的允许值包括:

-r option

为线程分析器收集数据争用检测或死锁检测数据。允许的值包括:

有关 collect -r 命令和线程分析器的更多信息,请参见《Sun Studio 12:线程分析器用户指南》tha.1 手册页。

实验控制选项

-F option

控制是否应当记录后续进程的数据。option 的允许值包括:

如果您指定 -F on 选项,收集器将跟踪通过调用函数 fork(2)、fork1(2)、fork(3F)、vfork(2) 和 exec(2) 及其变体而创建的进程。对 vfork 的调用已在内部被替换为对 fork1 的调用。

如果您指定 -F all 选项,收集器将跟踪所有后续进程,其中包括那些通过调用 system(3C)、system(3F)、sh(3F) 和 popen(3C) 以及类似函数而创建的后续进程以及与它们相关的后续进程。

如果您指定 -F '= regexp' 选项,收集器将跟踪其名称或沿袭与指定的正则表达式相匹配的所有后续进程。有关正则表达式的信息,请参见 regexp(5) 手册页。

当您在后续进程上收集数据时,收集器会针对创始实验中的每个后续进程打开一个新实验。这些新实验是通过向实验后缀添加一个下划线、一个字母和一个数字来命名的,如下所示:

例如,如果初始进程的实验名称是 test.1.er,则由它的第三个派生创建的子进程的实验是 test.1.er/_f3.er。如果该子进程针对新映像执行 exec 操作,则相应的实验名称为 test.1.er/_f3_x1.er。如果该子进程使用 popen 调用创建另一个进程,则实验名称为 test.1.er/_f3_x1_c1.er

分析器和 er_print 实用程序在读取创始实验后会自动读取后续进程的实验,但不会选择将后续进程的实验用于数据显示。

要从命令行中选择要显示的数据,请明确指定 er_printanalyzer 的路径名。所指定的路径必须包含创始实验的名称以及创始目录中后续实验的名称。

例如,要查看 test.1.er 实验的第三个派生的数据,需要指定以下内容:

er_print test.1.er/_f3.er

analyzer test.1.er/_f3.er

或者,可以使用感兴趣的后续实验的显式名称来准备实验组文件。

要在分析器中检查后续进程,请装入创始实验并从“视图”菜单中选择“过滤数据”。此时将显示一个实验列表,其中只有创始实验处于选中状态。取消选中初始实验并选中感兴趣的后续实验。


注 –

如果在后续进程正在被跟踪时创始进程退出,则可能会继续从后续进程中收集数据。创始实验目录会相应地继续变大。


-j option

当目标程序是 JVM 时,启用 Java 分析。option 的允许值包括:

如果要收集 .class 文件或 .jar 文件中的数据,则不需要 -j 选项,但前提是 java 可执行文件的路径在 JDK_HOME 环境变量或 JAVA_PATH 环境变量中。随后可以在 collect 命令行上将目标 program 指定为具有或不具有扩展名的 .class 文件或 .jar 文件。

如果无法在 JDK_HOMEJAVA_PATH 环境变量中定义java 的路径,或者要禁用对 Java HotSpot 虚拟机所编译的方法的识别,则可以使用 -j 选项。如果使用该选项,则在 collect 命令行上指定的 program 必须是版本不低于 1.5_03 的 Java 虚拟机。collect 命令验证 program 是否为 JVM 以及是否为 ELF 可执行文件;如果不是,collect 命令会列显一条错误消息。

如果要使用 64 位 JVM 收集数据,则不能将 java-d64 选项用于 32 位 JVM,否则将收集不到任何数据;相反,您必须在 collect 命令的 program 参数中或本节提供的两个环境变量之一中指定 64 位 JVM 的路径。

-J java_argument

指定要传递到用于分析的 JVM 的单个参数。如果您指定了 -J 选项但未指定 Java 分析,则会生成一个错误并且不运行实验。该参数作为单个参数传递到 JVM。如果需要多个参数,请不要使用 -J 选项,而是明确指定 JVM 的路径,使用 -j on,并在 collect 命令行上在 JVM 路径的后面添加 JVM 的参数。

-l signal

名为 signal 的信号传递到进程时,记录样本包。

可以通过全信号名、不带开始的几个字母 SIG 的信号名或信号编号来指定信号。请不要使用程序所使用的信号或会终止执行的信号。建议的信号为 SIGUSR1SIGUSR2。可通过 kill 命令将信号传递到进程。

如果同时使用 -l-y 选项,则必须针对每个选项使用不同的信号。

如果您使用该选项而程序具有其自己的信号处理程序,则应当确保使用 -l 指定的信号会传递到收集器的信号处理程序,而不是被截获或忽略。

有关信号的更多信息,请参见 signal(3HEAD) 手册页。

-t duration

指定数据收集的时间范围。

可以将 duration 指定为单个数字(可以选择添加 ms 后缀)以指示实验在该时间(单位为分钟或秒)终止。缺省情况下,持续时间以秒为单位。也可以将 duration 指定为用连字符分隔的两个这样的数字,这会导致数据收集暂停,直到经过第一个时间之后才开始收集数据。当到达第二个时间时,数据收集终止。如果第二个数字为零,则在初次暂停之后收集数据,直到该程序运行结束。即使该实验已经终止,也允许目标进程运行至结束。

-x

在从 exec 系统调用退出时使目标进程停止,以便允许调试器附加到目标进程。如果将 dbx 附加到目标进程,请使用 dbx 命令 ignore PROFignore EMT 来确保收集信号传递到 collect 命令。

-y signal[ ,r]

控制对包含名为 signal 的信号的数据的记录。无论何时将信号传递到进程,它都在暂停状态(在此期间不记录任何数据)和记录状态(在此期间记录数据)之间切换。无论切换状态如何,都将始终记录样本点。

可以通过全信号名、不带开始的几个字母 SIG 的信号名或信号编号来指定信号。请不要使用程序所使用的信号或会终止执行的信号。建议的信号为 SIGUSR1SIGUSR2。可通过 kill(1) 命令将信号传递到进程。

如果同时使用 -l-y 选项,则必须针对每个选项使用不同的信号。

使用 -y 选项时,如果已提供可选的 r 参数,则收集器将在记录状态下启动,否则将在暂停状态下启动。如果未使用 -y 选项,则收集器将在记录状态下启动。

如果您使用该选项而程序具有其自己的信号处理程序,则应当确保使用 -y 指定的信号会传递到收集器的信号处理程序,而不是被截获或忽略。

有关信号的更多信息,请参见 signal(3HEAD) 手册页。

输出选项

-o experiment_name

使用 experiment_name 作为要记录的实验的名称。experiment_name 字符串必须以字符串 ".er" 结尾;否则 collect 实用程序会列显一条错误消息并退出。

-d directory-name

将实验置于 directory-name 目录中。此选项仅适用于个别实验,而不适用于实验组。如果该目录不存在,则 collect 实用程序会列显一则错误消息并退出。如果使用 -g 选项指定了某个组,则该组文件也将写入 directory-name 中。

-g group-name

使实验成为实验组 group-name 的一部分。如果 group-name 不以 .erg 结尾,则 collect 实用程序会列显一条错误消息并退出。如果该组存在,则会将实验添加到该组中。如果 group-name 不是绝对路径并且使用 -d 指定了一个目录,则实验组将被置于 directory-name 目录中,否则,将被置于当前目录中。

-A option

控制是否应将目标进程所使用的装入对象归档或复制到已记录的实验中。option 的允许值包括:

如果您希望将实验从记录的位置复制到另一台计算机,或者从另一台计算机读取实验,请指定 -A copy。使用该选项不会将任何源文件或目标文件复制到实验中。您应当确保在要将实验复制到的计算机上可以访问这些文件。

-L size

将所记录的分析数据量限制在 size 兆字节。该限制适用于基于时钟的分析数据量、硬件计数器溢出分析数据量和同步等待跟踪数据量之和,但不适用于样本点。该限制只是近似值,可以被超出。

当达到该限制时,不再记录分析数据,但实验会一直保持打开状态,直到目标进程终止。如果启用了定期抽样,则会继续写入样本点。

记录的数据量的缺省限制为 2000 MB。选择该限制的原因是性能分析器无法处理所含数据量大于 2 GB 的实验。要去掉该限制,请将 size 设置为 unlimitednone

-O file

collect 本身的所有输出附加到名称 file,但是不重定向所产生的目标的输出。如果该文件设置为 /dev/null,则禁止 collect 的所有输出(包括任何错误消息)。

其他选项

-C comment

将注释放在实验的 notes 文件中。最多可以提供十个 -C 选项。该 notes 文件的内容会置于实验标题的前面。

-n

不运行目标,但列显在运行目标时要生成的实验的详细信息。此选项是模拟运行选项。

-R

在终端窗口中显示性能分析器自述文件的文本版本。如果未找到自述文件,则列显一条警告。不再检查任何参数,也不执行进一步的处理。

-V

列显 collect 命令的当前版本。不再检查任何参数,也不执行进一步的处理。

-v

列显 collect 命令的当前版本和正在运行的实验的详细信息。

使用 collect 实用程序从正在运行的进程中收集数据

可以将 -P pid 选项与 collect 实用程序一起使用来连接具有指定 PID 的进程并从该进程收集数据。collect 命令的其他选项被转换为 dbx 脚本,系统会调用该脚本来收集数据。只能收集基于时钟的分析数据(-p 选项)和硬件计数器溢出分析数据(-h 选项)。不支持跟踪数据。

如果在使用 -h 选项时未明确指定 -p 选项,则基于时钟的分析将处于关闭状态。要同时收集硬件计数器数据和基于时钟的数据,必须同时指定 -h 选项和 -p 选项。

Procedure使用 collect 实用程序从正在运行的进程中收集数据

  1. 确定程序的进程 ID (process ID, PID)。

    如果从命令行启动程序并将其放置在后台中,则其 PID 将由 shell 列显到标准输出中;否则,您可以通过键入以下内容来确定程序的 PID。


    % ps -ef | grep program-name
    
  2. 使用 collect 命令启用对该进程的数据收集功能并设置任何可选参数。


    % collect -P pid collect-options
    

    数据收集选项中对收集器选项进行了说明。有关基于时钟的分析的信息,请参见-p option。有关硬件时钟分析的信息,请参见-h option

使用 dbx collector 子命令收集数据

本节介绍如何从 dbx 运行收集器,然后介绍可以与 dbx 中的 collector 命令一起使用的每个子命令。

Proceduredbx 运行收集器:

  1. 通过键入以下命令将程序装入 dbx 中。


    % dbx program
    
  2. 使用 collector 命令启用数据收集,选择数据类型并设置任何可选参数。


    (dbx) collector subcommand
    

    要获取可用 collector 子命令的列表,请键入:


    (dbx) help collector
    

    必须针对每个子命令都使用一个 collector 命令。

  3. 设置要使用的任何 dbx选项并运行该程序。

    如果提供的子命令不正确,则会列显一条警告消息并忽略该子命令。下面是 collector 子命令的完整列表。

数据收集子命令

下列子命令控制收集器所收集的数据的类型。如果实验处于活动状态,则这些子命令将被忽略并显示一条警告。

profile option

控制对基于时钟的分析数据的收集。option 的允许值包括:

hwprofile option

控制对硬件计数器溢出分析数据的收集。如果您尝试在不支持硬件计数器溢出分析的系统中启用它,则 dbx 会返回一条警告消息,而且该命令将被忽略。option 的允许值包括:

synctrace option

控制对同步等待跟踪数据的收集。option 的允许值包括:

heaptrace option

控制对堆跟踪数据的收集。option 的允许值包括:

缺省情况下,收集器不收集堆跟踪数据。

mpitrace option

控制对 MPI 跟踪数据的收集。option 的允许值包括:

缺省情况下,收集器不收集 MPI 跟踪数据。

tha option

为线程分析器收集数据争用检测或死锁检测数据。允许的值包括:

有关线程分析器的更多信息,请参见《Sun Studio 12:线程分析器用户指南》tha.1 手册页。

sample option

控制抽样模式。option 的允许值包括:

缺省情况下,启用抽样间隔 value 为 1 秒的定期抽样。

dbxsample { on | off }

控制dbx 停止目标进程时对样本的记录。关键字的含义如下所示:

缺省情况下,在 dbx 停止目标进程时记录样本。

实验控制子命令

disable

禁用数据收集功能。如果进程正在运行而且正在收集数据,该子命令将终止实验并禁用数据收集功能。如果进程正在运行而且数据收集功能处于禁用状态,则该子命令将被忽略并显示一条警告。如果没有任何进程在运行,则该子命令将针对后续运行禁用数据收集功能。

enable

启用数据收集功能。如果进程正在运行,但数据收集功能处于禁用状态,则该子命令将启用数据收集功能并启动新的实验。如果进程正在运行,而且数据收集功能处于启用状态,则该子命令将被忽略并显示一条警告。如果没有任何进程在运行,则该子命令将针对后续运行启用数据收集功能。

您可以在任何进程执行期间根据需要启用和禁用数据收集功能任意次数。每次启用数据收集功能时,都会创建一个新实验。

pause

暂停数据收集,但使实验保持打开状态。收集器暂停时不记录样本点。在暂停之前会生成一个样本,在恢复之后会立即生成另一个样本。如果已暂停数据收集功能,则该子命令将被忽略。

resume

发出 pause 之后恢复数据收集。如果正在收集数据,则该子命令将被忽略。

sample record name

记录具有标签 name 的样本包。该标签显示在性能分析器的“事件”标签中。

输出子命令

下列子命令定义实验的存储选项。如果实验处于活动状态,则这些子命令将被忽略并显示一条警告。

archive mode

设置归档实验的模式。mode 的允许值包括:

如果打算将实验移到另一台计算机上,或者从另一台计算机上读取实验,则应当启用对装入对象的复制。如果实验处于活动状态,则该命令将被忽略并显示一条警告。该命令不会将源文件或目标文件复制到实验中。

limit value

所记录的分析数据量限制在 value 兆字节。该限制适用于基于时钟的分析数据量、硬件计数器溢出分析数据量和同步等待跟踪数据量之和,但不适用于样本点。该限制只是近似值,可以被超出。

当达到该限制时,不再记录分析数据,但实验会一直保持打开状态,而且会继续记录样本点。

记录的数据量的缺省限制为 2000 MB。选择该限制的原因是性能分析器无法处理所含数据量大于 2 GB 的实验。要去掉该限制,请将 value 设置为 unlimitednone

store option

控制实验的存储位置。如果实验处于活动状态,则该命令将被忽略并显示一条警告。option 的允许值包括:

信息子命令

show

显示每个收集器控件的当前设置。

status

报告任何打开的实验的状态。

使用 dbx 从正在运行的进程中收集数据

使用收集器可以从正在运行的进程中收集数据。如果进程已受 dbx 的控制,则可以暂停该进程并使用前几节中所描述的方法来启用数据收集。

如果进程不受 dbx 的控制,则可以使用 collect –P pid 命令从正在运行的进程中收集数据,如使用 collect 实用程序从正在运行的进程中收集数据中所述。您还可以向其附加 dbx,收集性能数据,然后从该进程分离并使进程继续运行。如果要为选定的后续进程收集性能数据,则必须将 dbx 附加到每个进程。

Procedure从正在运行且不受 dbx 控制的进程中收集数据:

  1. 确定程序的进程 ID (process ID, PID)。

    如果从命令行启动程序并将其放置在后台中,则其 PID 将由 shell 列显到标准输出中;否则,您可以通过键入以下内容来确定程序的 PID。


    % ps -ef | grep program-name
    
  2. 附加到该进程。

    dbx 键入以下内容。


    (dbx) attach program-name pid
    

    如果 dbx 尚未运行,请键入以下内容。


    % dbx program-name pid
    

    附加到正在运行的进程会使该进程暂停。

    有关附加到进程的更多信息,请参见《Sun Studio 12:使用 dbx 调试程序》

  3. 启动数据收集功能。

    dbx 中,使用 collector 命令来设置数据收集参数,使用 cont 命令来恢复执行进程。

  4. 从进程中分离。

    在完成对数据的收集之后,暂停该程序并从 dbx 中分离该进程。

    dbx 中键入以下内容。


    (dbx) detach
    

从正在运行的程序中收集跟踪数据

如果要收集任何种类的跟踪数据,则必须在运行程序之前预装入收集器库 libcollector.so,因为该库提供了能使数据收集发生的真正函数的包装。此外,收集器还将包装函数添加到其他系统库调用中,以保证性能数据的完整性。如果未预装入收集器库,则不能插入这些包装函数。有关收集器如何插入系统库函数的更多信息,请参见使用系统库

预装入 libcollector.so必须使用环境变量同时设置库的名称和库的路径,如下表中所示。使用环境变量 LD_PRELOAD 设置库的名称。使用环境变量 LD_LIBRARY_PATHLD_LIBRARY_PATH_32LD_LIBRARY_PATH_64 设置库的路径。如果未定义 _32_64 变量,则使用 LD_LIBRARY_PATH。如果已经定义了这些环境变量,则向其中添加新值。

表 3–2 用来预装入 libcollector.so 库的环境变量设置

环境变量 

值 

LD_PRELOAD

libcollector.so

LD_LIBRARY_PATH

/opt/SUNWspro/prod/lib/dbxruntime

LD_LIBRARY_PATH_32

/opt/SUNWspro/prod/lib/dbxruntime

LD_LIBRARY_PATH_64

/opt/SUNWspro/prod/lib/v9/dbxruntime

LD_LIBRARY_PATH_64

/opt/SUNWspro/prod/lib/amd64/dbxruntime

如果 Sun Studio 软件未安装在 /opt/SUNWspro 中,请向系统管理员咨询正确的路径。可以在 LD_PRELOAD 中设置全路径,但是,当使用 SPARC V9 64 位体系结构时,这样做会使问题复杂化。


注 –

运行后删除 LD_PRELOADLD_LIBRARY_PATH 设置,以便它们对于从同一个 shell 启动的其他程序无效。


如果要从已在运行的 MPI 程序收集数据,则必须将一个单独的 dbx 实例附加到每个进程并针对每个进程启用收集器。在将 dbx 附加到 MPI 作业中的多个进程时,每个进程将被停止并在不同的时间重新启动。时间差异可能会更改 MPI 进程间的交互并影响所收集的性能数据。为了使该问题带来的影响最小,一种解决方案是使用 pstop(1) 命令停止所有进程。但是,在将 dbx 附加到这些进程后,必须从 dbx 重新启动这些进程,重新启动进程时会发生时间延迟,这会影响 MPI 进程的同步。另请参见从 MPI 程序收集数据

从 MPI 程序收集数据

收集器可以从那些使用消息传递接口 (Message Passing Interface, MPI) 库的多进程程序中收集性能数据。Open MPI 库包含在 Sun HPC ClusterToolsTM 7 软件中,Sun MPI 库包含在 ClusterTools 5 和 ClusterTools 6 软件中。可从 http://www.sun.com/software/products/clustertools/ 获取 ClusterTools 软件。

要在使用 ClusterTools 7 时启动并行作业,请使用 Open Run-Time Environment (ORTE) 命令 mpirun

要在使用 ClusterTools 5 或 ClusterTools 6 时启动并行作业,请使用 Sun Cluster Runtime Environment (CRE) 命令 mprun

有关更多信息,请参见 Sun HPC ClusterTools 文档

有关 MPI 和 MPI 标准的信息,请参见 MPI Web 站点 http://www.mcs.anl.gov/mpi/。有关 Open MPI 的更多信息,请参见 Web 站点 http://www.open-mpi.org/

由于 MPI 和收集器的实现方式,每个 MPI 进程记录一个单独的实验。每个实验必须具有唯一的名称。实验的存储位置和方式取决于 MPI 作业可用的文件系统类型。有关存储实验的问题将在下一个小节存储 MPI 实验中讨论。

要从 MPI 作业收集数据,可以在 MPI 下运行 collect 命令,也可以在 MPI 下启动 dbx 并使用 dbx collector 子命令。这些任务将在在 MPI 下运行 collect 命令通过在 MPI 下启动 dbx 来收集数据中讨论。

存储 MPI 实验

由于多进程环境比较复杂,因此从 MPI 程序收集性能数据时应当注意一些有关存储 MPI 实验的问题。这些问题涉及到数据收集和存储的效率以及实验的命名。有关命名实验(包括 MPI 实验)的信息,请参见数据的存储位置

用来收集性能数据的每个 MPI 进程都创建其自己的实验。当某个 MPI 进程创建实验时,它会锁定实验目录。所有其他 MPI 进程都必须等到该锁定被释放之后才能使用此目录。因此,如果将实验存储到所有 MPI 进程都可以访问的文件系统,则会按顺序创建这些实验;但是如果将实验存储到每个 MPI 进程的本地文件系统,则会并行创建这些实验。

如果允许收集器创建实验名称,则可以避免与实验名称和存储位置有关的问题。请参见下一节缺省的 MPI 实验名称

缺省的 MPI 实验名称

如果未指定实验名称,则使用缺省的实验名称。收集器使用 MPI 等级以标准格式 experiment.m.er 构造实验名称,其中 m 是 MPI 等级。如果指定了实验组,则主干 experiment 为实验组名称的主干,否则主干为 test。无论使用的是公共文件系统还是本地文件系统,实验名称都是唯一的。因此,如果使用本地文件系统记录实验并将其复制到公共文件系统,则复制这些实验并重新构造任何实验组文件时不必重命名实验。在多数情况下,您应当允许收集器创建实验名称,以确保名称在所有文件系统的范围内是唯一的。

指定非缺省的 MPI 实验名称

如果您将实验存储在公共文件系统上,并以标准格式 experiment. n.er 指定实验名称,那么当每个实验的 n 值递增时,每个实验将被赋予一个唯一的名称。实验是按照 MPI 进程获取实验目录锁的顺序来编号的,因而无法保证与进程的 MPI 等级相对应。如果您将 dbx 附加到正在运行的 MPI 作业中的 MPI 进程,则实验编号由附加的顺序来确定。

如果您将每个实验都存储在其自己的本地文件系统上并指定一个显式的实验名称,则每个实验都可能会获得这个名称。例如,假设您在具有四个单处理器节点的群集中运行 MPI 作业,这四个节点分别标记为 node0node1node2node3。每个节点具有一个名为 /scratch 的本地磁盘,您将实验存储在该磁盘的 username 目录中。由 MPI 作业创建的实验具有下面的全路径名称。


node0:/scratch/username/test.1.er
node1:/scratch/username/test.1.er
node2:/scratch/username/test.1.er
node3:/scratch/username/test.1.er

包括节点名称的全名是唯一的,但在每个实验目录中都有一个名为 test.1.er 的实验。如果在 MPI 作业完成后将实验移到公共位置,则必须确保这些名称仍然是唯一的。例如,要将这些实验移到假设可以从所有节点访问的起始目录并重命名这些实验,请键入以下命令。


rsh node0 ’er_mv /scratch/username/test.1.er test.0.er’
rsh node1 ’er_mv /scratch/username/test.1.er test.1.er’
rsh node2 ’er_mv /scratch/username/test.1.er test.2.er’
rsh node3 ’er_mv /scratch/username/test.1.er test.3.er’

对于大型 MPI 作业,可能需要使用脚本将实验移到公共位置。请不要使用 UNIX® 命令 cpmv;应当使用上例中所示的 er_cper_mv,如处理实验中所述。

如果不知道哪些本地文件系统可用,请使用 df -lk 命令或咨询系统管理员。请始终确保用来存储实验的目录已经存在、其定义是唯一的以及不将其用于任何其他实验,还要确保文件系统具有足够的空间来容纳这些实验。有关如何估计所需空间的信息,请参见估计存储要求


注 –

除非您能够访问用于运行实验的装入对象和源文件或者拥有具备相同路径和时间戳的副本,否则在计算机或节点间复制或移动实验时不能在带注释的反汇编代码中查看带注释的源代码或源代码行。


在 MPI 下运行 collect 命令

要在 MPI 的控制下使用 collect 命令收集数据,,请使用与 ClusterTools 版本相对应的语法,如下所示。

在 Sun HPC ClusterTools 7 上:


% mpirun -np n 
collect [collect-arguments] program-name
 [program-arguments]

在 Sun HPC ClusterTools 6 和更低版本上:


% mprun -np n 
collect [collect-arguments] program-name
 [program-arguments]

在以上两种情况下,n 都表示要由 MPI 创建的进程数。此过程会创建 n 个单独的 collect 实例,每个实例都记录一个实验。有关实验的存储位置和方法的信息,请阅读数据的存储位置一节。

为了确保将来自不同 MPI 运行的实验集存储在不同的位置,可以使用 -g 选项为每个 MPI 运行创建一个实验组。实验组应当存储在所有 MPI 进程都可以访问的文件系统上。创建实验组还有助于将单个 MPI 运行的实验集装入性能分析器。如果不创建组,则可以使用 -d 选项为每个 MPI 运行指定一个单独的目录。

通过在 MPI 下启动 dbx 来收集数据

要在 MPI 的控制下启动 dbx 并收集数据,请使用下面的语法。

在 Sun HPC ClusterTools 7 上:


% mpirun -np n dbx program-name < collection-script

在 Sun HPC ClusterTools 6 或更低版本上:


% mprun -np n dbx program-name < collection-script

在以上两种情况下,n 都表示要由 MPI 创建的进程数,collection-script 都表示包含设置和启动数据收集所必需的命令的 dbx 脚本。此过程会创建 n 个单独的 dbx 实例,每个实例都记录其中一个 MPI 进程上的实验。如果未定义实验名称,则使用 MPI 等级对实验进行标记。有关实验的存储位置和方法的信息,请阅读存储 MPI 实验一节。

通过在程序中使用收集脚本以及对 MPI_Comm_rank() 的调用,可以使用 MPI 等级来对实验进行命名。例如,在 C 程序中插入以下行。


ier = MPI_Comm_rank(MPI_COMM_WORLD,&me);

在 Fortran 程序中插入以下行。


call MPI_Comm_rank(MPI_COMM_WORLD, me, ier)

例如,如果将该调用插入到第 17 行,则可以使用类似以下内容的脚本。


stop at 18
run program-arguments
rank=$[me]
collector enable
collector store filename experiment.$rank.er
cont
quit
 

collectppgsz 一起使用

通过在 ppgsz 命令上运行 collect 并指定 -F on-F all 标志,可以将 collect ppgsz(1) 一起使用。创始实验位于 ppgsz 可执行文件上,我们不需要关注它。如果您的路径找到 32 位版本的 ppgsz,并且实验在支持 64 位进程的系统上运行,则首先要做的是针对它的 64 位版本执行 exec,创建 _x1.er。该可执行文件将进行派生,创建 _x1_f1.er

子进程尝试针对路径上的第一个目录中指定的目标执行 exec,然后针对第二个目录中的目标执行 exec,依此类推,直到其中一个 exec 尝试成功。例如,如果第三个尝试成功,则前两个后续实验分别命名为 _x1_f1_x1.er_x1_f1_x2.er,并且这两个实验都完全为空。目标上的实验是来自成功的 exec 的某个实验(在本例中为第三个实验),命名为 _x1_f1_x3.er 并存储在创始实验之下。通过针对 test.1.er/_x1_f1_x3.er 调用分析器或 er_print 实用程序,可以直接处理该目标。

如果 64 位 ppgsz 是初始进程,或者如果在 32 位内核上调用 32 位 ppgsz,那么,针对实际目标执行 exec 操作的派生子进程的数据位于 _f1.er 中,而实际目标的实验位于 _f1_x3.er 中,前提是采用与上例相同的路径。