Sun Studio 12 Update 1:OpenMP API 用户指南

6.4 检查自动作用域的结果

使用编译器注释可检查自动确定作用域的结果,并确定是否因自动确定作用域失败而导致将并行区域序列化。

使用 -g 调试选项编译时,编译器将生成行内注释。可以使用 er_src 命令查看这个生成的注释,如下所示。(er_src 命令作为 Sun Studio 软件的一部分提供;有关更多信息,请参见 er_src(1) 手册页或 Sun Studio 性能分析器手册。)

使用 -xvpara 选项进行编译是一个良好的开端。如果自动确定作用域失败,将输出警告消息(如下所示)。


示例 6–1 使用 -vpara 进行编译


%cat t.f
      INTEGER X(100), Y(100), I, T
C$OMP PARALLEL DO DEFAULT(__AUTO)
      DO I=1, 100
         T = Y(I)
         CALL FOO(X)
         X(I) = T*T
      END DO
C$OMP END PARALLEL DO
      END
%f95 -xopenmp -xO3 -vpara -c t.f
"t.f", line 2: Warning: parallel region will be executed 
   by a single thread because the autoscoping 
   of following variables failed - x

使用 f95-vparacc-xvpara 进行编译。(CC 中尚未实现此选项。)


示例 6–2 使用编译器注释


%cat t.f
      INTEGER X(100), Y(100), I, T
C$OMP PARALLEL DO DEFAULT(__AUTO)
      DO I=1, 100
         T = Y(I)
         X(I) = T*T
      END DO
C$OMP END PARALLEL DO
      END

%f95 -xopenmp -xO3 -g -c t.f
%er_src t.o
Source file: ./t.f
Object file: ./ot.o
Load Object: ./t.o

     1. INTEGER X(100), Y(100), I, T

Source OpenMP region below has tag R1
Variables autoscoped as SHARED in R1: x, y
Variables autoscoped as PRIVATE in R1: t, i
Private variables in R1: i, t
Shared variables in R1: y, x
     2. C$OMP PARALLEL DO DEFAULT(__AUTO)
       <Function: _$d1A2.MAIN_>
Source loop below has tag L1
L1 parallelized by explicit user directive
L1 parallel loop-body code placed in function _$d1A2.MAIN_ along with 0
inner loops
Copy in M-function of loop below has tag L2
L2 scheduled with steady-state cycle count = 3
L2 unrolled 4 times
L2 has 0 loads, 0 stores, 2 prefetches, 0 FPadds, 0 FPmuls, and 0 FPdivs
per iteration
L2 has 1 int-loads, 1 int-stores, 4 alu-ops, 1 muls, 0 int-divs and 1
shifts per iteration
     3. DO I=1, 100
     4. T = Y(I)
     5. X(I) = T*T
     6. END DO
     7. C$OMP END PARALLEL DO
     8. END

接下来,使用一个更复杂的示例来解释自动作用域规则的应用方式。


示例 6–3 更复杂的示例


 1.      REAL FUNCTION FOO (N, X, Y)
 2.      INTEGER       N, I
 3.      REAL          X(*), Y(*)
 4.      REAL          W, MM, M
 5.
 6.      W = 0.0
 7.
 8. C$OMP PARALLEL DEFAULT(__AUTO)
 9.
10. C$OMP SINGLE
11.       M = 0.0
12. C$OMP END SINGLE
13.
14.       MM = 0.0
15.
16. C$OMP DO
17.       DO I = 1, N
18.          T = X(I)
19.          Y(I) = T
20.          IF (MM .GT. T) THEN
21.             W = W + T
22.             MM = T
23.          END IF
24.       END DO
25. C$OMP END DO
26.
27. C$OMP CRITICAL
28.       IF ( MM .GT. M ) THEN
29.          M = MM
30.       END IF
31. C$OMP END CRITICAL
32.
33. C$OMP END PARALLEL
34.
35.      FOO = W - M
36.
37.      RETURN
38.      END

函数 FOO() 包含一个并行区域,该并行区域包含一个 SINGLE 构造、一个工作共享 DO 构造和一个 CRITICAL 构造。如果我们忽略所有 OpenMP 并行构造,则并行区域中的代码所执行的操作如下:

  1. 将数组 X 中的值复制到数组 Y

  2. 查找 X 中的最大正数值,并将其存储在 M

  3. X 的一些元素的值累加到变量 W 中。

让我们看一下编译器如何使用上述规则来查找并行区域中变量的相应作用域。

在并行区域中使用下列变量:INMMTWMXY。编译器将确定以下内容。