# OpenMP* Examples

The following examples show how to use several OpenMP* features.

## A Simple Difference Operator

This example shows a simple parallel loop where the amount of work in each iteration is different. Dynamic scheduling is used to improve load balancing.

The `END DO` directive has a `NOWAIT` clause because there is an implicit barrier at the end of the parallel region. Therefore it is not necessary to also have a barrier at the end of the `DO` region.

    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

## Two Difference Operators: DO Loop Version

This example uses two parallel loops fused to reduce fork/join overhead. The first `END DO` directive has a NOWAIT clause because all the data used in the second loop is different than all the data used in the first loop.

    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

## Two Difference Operators: SECTIONS Version

This example demonstrates the use of the `SECTIONS` directive. The logic is identical to the preceding `DO` directive example, but uses a `SECTIONS` directive instead of a `DO` directive. Here the speedup is limited to two because there are only two units of work whereas in the example above there are `(n-1) + (m-1)` units of work.

    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

## Update a Shared Scalar

This example demonstrates how to use a `SINGLE` construct to update an element of the shared array a. The optional `NOWAIT` clause after the first loop is omitted because it is necessary to wait at the end of the loop before proceeding into the `SINGLE` construct to avoid a race condition.

    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

Parent topic: OpenMP* Support