インテル® Fortran コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス

OpenMP* の例

次の例では、いくつかの OpenMP* 機能の使用方法を示します。

単純な差分演算子

この例は、各繰り返しごとにワーク量が異なる単純な並列ループを示したものです。負荷のバランスを向上させるため、動的スケジュールを使用しています。

並列領域の最後に暗黙的な barrier があるため、END DONOWAIT が含まれています。

subroutine do_1(a,b,n)
  real a(n,n), b(n,n)
  !$OMP PARALLEL SHARED(A,B,N)
     !$OMP DO SCHEDULE(DYNAMIC,1) PRIVATE(I,J)
       do i = 2, n
          do j = 1, i
            b(j,i) = ( a(j,i) + a(j,i-1) ) / 2.0
          end do
      end do
  !$OMP END DO NOWAIT 
!$OMP END PARALLEL 
end

2 つの差分演算子: DO ループバージョン

例では、fork/join のオーバーヘッドを減らすために融合される 2 つの並列ループを使用します。2 番目のループで使用するすべてのデータは最初のループで使用されるすべてのデータと異なるため、最初の END DO ディレクティブには、NOWAIT 節が含まれています。

subroutine do_2(a,b,c,d,m,n)
  real a(n,n), b(n,n), c(m,m), d(m,m)
  !$OMP PARALLEL SHARED(A,B,C,D,M,N) PRIVATE(I,J)
    !$OMP DO SCHEDULE(DYNAMIC,1)
       do i = 2, n
        do j = 1, i
          b(j,i) = ( a(j,i) + a(j,i-1) ) / 2.0
        end do
      end do
    !$OMP END DO NOWAIT
    !$OMP DO SCHEDULE(DYNAMIC,1)
      do i = 2, m
        do j = 1, i
          d(j,i) = ( c(j,i) + c(j,i-1) ) / 2.0
        end do
      end do
    !$OMP END DO NOWAIT
  !$OMP END PARALLEL 
end

2 つの差分演算子: SECTIONS バージョン

例では、SECTIONS ディレクティブの使用方法を示します。ロジックは、前述の DO の例と同じですが、DO の代わりに SECTIONS を使用します。ここでは、2 つの作業単位しかないため、スピードアップは、2 が限度です。前述の例では、作業単位は (n-1) + (m-1) です。

subroutine sections_1(a,b,c,d,m,n)
  real a(n,n), b(n,n), c(m,m), d(m,m)
  !$OMP PARALLEL SHARED(A,B,C,D,M,N) PRIVATE(I,J)
    !$OMP SECTIONS
       !$OMP SECTION
          do i = 2, n
             do j = 1, i
                b(j,i)=( a(j,i) + a(j,i-1) ) / 2.0
             end do
          end do
       !$OMP SECTION
          do i = 2, m
             do j = 1, i
                d(j,i)=( c(j,i) + c(j,i-1) ) / 2.0
             end do
          end do
    !$OMP END SECTIONS NOWAIT
  !$OMP END PARALLEL 
end

共有スカラーの更新

この例では、共有配列 a の要素を更新する SINGLE 構造の使用方法を示します。最初のループの後にくるオプションの nowait 節は取り除かれています。これは、SINGLE 構造に進む前にループの最後で待機する必要があるためです。

subroutine sp_1a(a,b,n)
  real a(n), b(n)
  !$OMP PARALLEL SHARED(A,B,N) PRIVATE(I)
    !$OMP DO
       do i = 1, n
         a(i) = 1.0 / a(i)
       end do
    !$OMP SINGLE
      a(1) = min( a(1), 1.0 )
    !$OMP END SINGLE
    !$OMP DO
      do i = 1, n
        b(i) = b(i) / a(i)
      end do
    !$OMP END DO NOWAIT
  !$OMP END PARALLEL 
end