Oracle® Developer Studio 12.5:线程分析器用户指南

退出打印视图

更新时间: 2016 年 6 月
 
 

了解实验结果

本节介绍如何使用 er_print 命令行和线程分析器显示检测到的每次数据争用的以下信息:

  • 数据争用的唯一 ID。

  • 与数据争用相关联的虚拟地址 Vaddr。如果不止一个虚拟地址,则会在括号中显示标签 Multiple Addresses(多个地址)。

  • 两个不同线程对虚拟地址 Vaddr 的内存访问。将会显示访问的类型(读取或写入),以及源代码中发生访问的函数、偏移量和行号。

  • 与数据争用相关联的调用堆栈跟踪总数。每个跟踪都引用发生两个数据争用访问时的一对线程调用堆栈。

    如果使用的是线程分析器,则在 "Races"(争用)视图中选择单个调用堆栈跟踪时会在 "Race Details"(争用详细信息)窗口中显示这两个调用堆栈。如果使用的是 er_print 实用程序,rdetail 命令将会显示这两个调用堆栈。

prime_omp.c 中的数据争用

要检查 prime_omp.c 中的数据争用,可以使用在创建数据争用检测实验中创建的实验之一。

要使用 er_print 显示 prime_omp_instr.er 实验中的数据争用信息,请键入以下命令。

% er_print prime_omp_inst.er

(er_print) 提示符下,键入 races 可看到类似如下的输出:

(er_print) races

Total Races:  4 Experiment:  prime_omp_inst.er
    
Race #1, Vaddr: 0x21850
         Access 1: Write, line 25 in "prime_omp.c",
                   is_prime
         Access 2: Read, line 22 in "prime_omp.c",
                   is_prime
 Total Callstack Traces: 1

Race #2, Vaddr: (Multiple Addresses)
         Access 1: Write, line 49 in "prime_omp.c",
                   main
         Access 2: Write, line 49 in "prime_omp.c",
                   main
 Total Callstack Traces: 1
             
Race #3, Vaddr: 0xffbff534
         Access 1: Write, line 50 in "prime_omp.c",
                   main
         Access 2: Read, line 49 in "prime_omp.c",
                   main
 Total Callstack Traces: 1
             
Race #4, Vaddr: 0xffbff534
         Access 1: Write, line 50 in "prime_omp.c",
                   main
         Access 2: Write, line 50 in "prime_omp.c",
                   main
Total Callstack Traces: 1
(er_print)

该程序的此次特定运行期间发生了四次数据争用。

要在线程分析器中打开 prime_omp_inst.er 实验,请键入以下命令:

% tha prime_omp_inst.er

以下屏幕抓图显示了在 prime_omp.c 中检测到的争用,如线程分析器所显示。

图 1  prime_omp.c 中检测到的数据争用

image:线程分析器窗口的屏幕抓图,显示了关于 prime_omp.c 数据争用的 “Races“(争用)视图。

    prime_omp.c 中显示了四次数据争用:

  • Race #1(争用 1)显示了第 25 行函数 is_prime() 中的一次写入与第 22 行同一函数中的一次读取之间的争用。如果查看源代码,可以看到在这些行上,正在对 pflag[ ] 数组进行访问。在线程分析器中,通过单击 "Dual Source"(双源)视图可以很方便地查看位于两个行号位置的源代码,其中还有一些度量显示受影响的代码行上的争用访问次数。

  • Race #2(争用 2)显示了对 main 函数第 49 行的两次写入之间的争用。单击 "Dual Source"(双源)视图可看到,多次尝试访问第 49 行上 primes [ ] 数组的元素。"Race #2"(争用 2)表示在数组 primes[ ] 的不同元素中发生的一组数据争用。通过 Vaddr 显示 Multiple Addresses(多个地址)可以看出这一点。

  • Race #3(争用 3)显示了第 50 行 main 函数中的一次写入与第 49 行同一函数中的一次读取之间的争用。如果查看源代码,可以看到在这些行上,正在对可变 total 进行访问。

  • Race #4(争用 4)显示了对 main 函数第 50 行的两次写入之间的争用。如果查看源代码,可以看到在这些行上,正在对可变 total 进行更新。

    使用线程分析器中的 "Dual Source"(双源)视图,可以同时看到与数据争用相关联的两个源代码位置。例如,在 "Races"(争用)视图中为 prime_omp.c 选择 Race #1(争用 1),然后单击 "Dual Source"(双源)视图。将会看到类似如下的内容。

使用线程分析器中的 "Dual Source"(双源)视图,可以同时看到与数据争用相关联的两个源代码位置。例如,在 "Races"(争用)视图中为 prime_pthr.c 选择 Race #3(争用 3),然后单击 "Dual Source"(双源)视图。将会看到类似如下的内容。

图 2  prime_omp.c 中检测到的数据争用的源代码

image:线程分析器窗口的屏幕抓图,显示了关于 prime_omp.c 数据争用的 “Dual Source“(双源)视图。

prime_pthr.c 中的数据争用

要检查 prime_pthr.c 中的数据争用,可以使用在创建数据争用检测实验中创建的实验之一。

要使用 er_print 显示 prime_pthr_instr.er 实验中的数据争用信息,请键入以下命令:

% er_print prime_pthr_inst.er

(er_print) 提示符下,键入 races 可看到类似如下的输出:

(er_print) races

Total Races:  5 Experiment:  prime_pthr_inst.er

Race #1, Vaddr: (Multiple Addresses)
Access 1: Write, line 26 in "prime_pthr.c",
          is_prime + 0x00000234
Access 2: Write, line 26 in "prime_pthr.c",
          is_prime + 0x00000234
Total Callstack Traces: 2

Race #2, Vaddr: 0xffbff6dc
Access 1: Write, line 59 in "prime_pthr.c",
          main + 0x00000208
Access 2: Read, line 39 in "prime_pthr.c",
          work + 0x00000070
Total Callstack Traces: 1

Race #3, Vaddr: 0x21620
Access 1: Write, line 44 in "prime_pthr.c",
          work + 0x000001C0
Access 2: Read, line 43 in "prime_pthr.c",
          work + 0x0000011C
Total Callstack Traces: 2

Race #4, Vaddr: 0x21620
Access 1: Write, line 44 in "prime_pthr.c",
          work + 0x000001C0
Access 2: Write, line 44 in "prime_pthr.c",
          work + 0x000001C0
Total Callstack Traces: 2

Race #5, Vaddr: (Multiple Addresses)
Access 1: Write, line 43 in "prime_pthr.c",
          work + 0x00000174
Access 2: Write, line 43 in "prime_pthr.c",
          work + 0x00000174
Total Callstack Traces: 2
(er_print)

该程序的此次特定运行期间发生了五次数据争用。

要在线程分析器中打开 prime_pthr_inst.er 实验,请键入以下命令:

% tha prime_pthr_inst.er

以下屏幕抓图显示了在 prime_pthr.c 中检测到的争用,如线程分析器所显示。请注意,这些争用与 er_print 所显示的争用相同。

图 3  prime_pthr.c 中检测到的数据争用

image:线程分析器窗口的屏幕抓图,显示了关于 prime_pthr.c 数据争用的 “Races“(争用)视图

prime_pthr.c 中显示了五次数据争用:

  • Race #1(争用 1)是第 26 行上函数 is_prime()pflag[ ] 数组元素的两次写入之间的数据争用。

  • Race #2(争用 2)是第 59 行中对 main() 中内存位置 i 的一次写入与第 39 行中对同一内存位置(在 work() 中名为 *arg)的一次读取之间的数据争用。

  • Race #3(争用 3)是第 44 行中对 total 的一次写入与第 43 行中对 total 的一次读取之间的数据争用。

  • Race #4(争用 4)是第 44 行中对 total 的一次写入与同一行中对 total 的另一次写入之间的数据争用。

  • Race #5(争用 5)是 main() 函数第 43 行的两次写入之间的数据争用。Race #5(争用 3)表示数组 primes[ ] 的不同元素中所发生的一组数据争用。通过 Vaddr 显示 Multiple Addresses(多个地址)可以看出这一点。

如果选择 Race #3(争用 3),然后单击 "Dual Source"(双源)视图,则会看到两个源代码位置,类似于以下屏幕抓图。

图 4  数据争用的源代码详细信息

image:线程分析器窗口的屏幕抓图,显示了 “Dual Source“(双源)视图。

Race #2(争用 2)的第一次访问位于第 59 行,显示在顶部面板中。第二次访问位于第 39 行,显示在底部面板中。源代码的左侧会突出显示 "Race Accesses"(争用访问)度量。此度量显示了该行上报告的数据争用访问总次数。

数据争用的调用堆栈跟踪

线程分析器的 "Races"(争用)视图中列出的每次数据争用还有一个或多个相关联的调用堆栈跟踪。这些调用堆栈显示了代码中导致数据争用的执行路径。单击调用堆栈跟踪时,右侧面板中的 "Race Details"(争用详细信息)窗口会显示导致数据争用的函数调用。

图 5  "Races"(争用)视图(包含 prime_omp.c 的调用堆栈跟踪)

image:线程分析器窗口的屏幕抓图,其中显示的 “Race Details“(争用详细信息)窗口包含了 prime_omp.c 中的数据争用的调用堆栈跟踪