Oracle® Solaris Studio 12.4:线程分析器用户指南

退出打印视图

更新时间: 2014 年 12 月
 
 

使用线程分析器的提示

本附录介绍关于使用线程分析器的一些提示信息。

编译应用程序

    关于在收集实验之前编译应用程序的提示:

  • 生成应用程序二进制代码时,使用 –g 编译器选项。通过该选项,线程分析器可以报告数据争用和死锁的行号信息。

  • 生成应用程序二进制代码时,使用低于 –xO3 的优化级别进行编译。编译器转换可能会误报行号信息并使结果难以理解。

  • 线程分析器会插入内存分配 API中所示的例程。链接到内存分配库的归档版本可能会导致误报数据争用。

检测应用程序以检测数据争用

    关于在收集实验之前检测应用程序以检测数据争用的提示:

  • 如果没有检测二进制代码以进行数据争用检测,collect -r race 命令会发出一条如下所示的警告:

    % collect -r races a.out
      WARNING: Target `a.out' is not instrumented for datarace
      detection; reported datarace data may be misleading
  • 通过使用 nm 命令以及查找对 tha 例程的调用,可以确定是否检测了二进制代码以进行数据争用检测。如果显示名称以 __tha_ 开头的例程,则表明已检测二进制代码。示例输出如下所示。

    源代码级检测:

    % cc -xopenmp -g -xinstrument=datarace source.c
    % nm a.out | grep __tha_
      [71] | 135408| 0|FUNC |GLOB |0 |UNDEF |__tha_get_stack_id
      [53] | 135468| 0|FUNC |GLOB |0 |UNDEF |__tha_src_read_w_frame
      [61] | 135444| 0|FUNC |GLOB |0 |UNDEF |__tha_src_write_w_frame

    二进制代码级检测:

    % cc -xopenmp -g source.c
    % discover -i datarace -o a.out.i a.out
    % nm a.out.i | grep __tha_
      [88] | 0| 0|NOTY |GLOB |0 |UNDEF |__tha_read_w_pc_frame
      [49] | 0| 0|NOTY |GLOB |0 |UNDEF |__tha_write_w_pc_frame

使用 collect 命令运行应用程序

    关于运行检测后的应用程序以检测数据争用和死锁的提示。

  • 确保 Oracle Solaris 系统已安装了所有必需的修补程序。collect 命令可列出所有缺少的必需修补程序。对于 OpenMP 应用程序,需要安装最新版本的 libmtsk.so

  • 检测可能会导致执行时间显著延长(高达 50 倍甚至更多),还会导致内存消耗增加。可以尝试通过使用较小的数据集缩短执行时间。也可以尝试通过增加线程数缩短执行时间。

  • 为检测数据争用,请确保应用程序当前使用的线程不止一个。对于 OpenMP,您可以指定线程数,方法是将环境变量 OMP_NUM_THREADS 设置为所需的线程数并将环境变量 OMP_DYNAMIC 设置为 FALSE

报告数据争用

    关于报告数据争用的提示:

  • 线程分析器检测运行时的数据争用。应用程序的运行时行为取决于使用的输入数据集和操作系统调度。请通过使用不同的线程数以及使用不同的输入数据集,在 collect 下运行应用程序。还应使用单个数据集重复进行实验,以最大限度地提高该工具检测到数据争用的可能性。

  • 线程分析器检测从单个进程产生的不同线程之间的数据争用。它不检测不同进程之间的数据争用。

  • 线程分析器不报告数据争用中访问的变量的名称。但是,若要确定变量的名称,可以检查发生两次数据争用访问的源代码行,再找出这些源代码行上写入的变量和读取的变量。

  • 在某些情况下,线程分析器可能会报告实际在程序中并未发生的数据争用。这些数据争用称为误报。使用由用户实现的同步时或在线程之间回收内存时,通常会发生这种情况。例如,如果代码中包含实现自旋锁的手编程序集,线程分析器将无法识别这些同步点。通过在源代码中插入对线程分析器用户 API 的调用,可让线程分析器知道有关用户定义的同步的情况。有关更多信息,请参见误报Appendix A, 线程分析器可识别的 API

  • 使用源代码级别检测报告的数据争用与使用二进制代码级别检测报告的数据争用可能不相同。在二进制代码级别检测中,缺省情况下会在打开共享库时检测这些共享库(无论它们是静态链接到程序中的,还是通过 dlopen() 动态打开的)。在源代码级检测中,仅当使用 –xinstrument=datarace 编译库的源代码时,才会对库进行检测。