# 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 `for` pragma 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 `for` region.

    void for1(float a[], float b[], int n) {
      int i, j;
      #pragma omp parallel shared(a,b,n) {
       #pragma omp for schedule(dynamic,1) private (i,j) nowait
        for (i = 1; i < n; i++)
           for (j = 0; j < i; j++)
             b[j + n*i] = (a[j + n*i] + a[j + n*(i-1)]) / 2.0;
      }
    }

## Two Difference Operators: for Loop Version

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

    void for2(float a[], float b[], float c[], float d[], int n, int m) {
      int i, j;
      #pragma omp parallel shared(a,b,c,d,n,m) private(i,j) {
        #pragma omp for schedule(dynamic,1) nowait
        for (i = 1; i < n; i++)
          for (j = 0; j < i; j++)
            b[j + n*i] = ( a[j + n*i] + a[j + n*(i-1)] )/2.0;
        #pragma omp for schedule(dynamic,1) nowait
        for (i = 1; i < m; i++)
          for (j = 0; j < i; j++)
            d[j + m*i] = ( c[j + m*i] + c[j + m*(i-1)] )/2.0;
      }
    }

## Two Difference Operators: sections Version

This example demonstrates the use of the `sections` pragma . The logic is identical to the preceding `for` pragma example, but uses a `sections` pragma instead of a `for` pragma . 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.

    void sections1(float a[], float b[], float c[], float d[], int n, int m) {
      int i, j;
      #pragma omp parallel shared(a,b,c,d,n,m) private(i,j) {
        #pragma omp sections nowait {
          #pragma omp section
           for (i = 1; i < n; i++)
             for (j = 0; j < i; j++)
               b[j + n*i] = ( a[j + n*i] + a[j + n*(i-1)] )/2.0;
          #pragma omp section
           for (i = 1; i < m; i++)
             for (j = 0; j < i; j++)
               d[j + m*i] = ( c[j + m*i] + c[j + m*(i-1)] )/2.0;
         }
       }
    }

## 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.

    void sp_1a(float a[], float b[], int n) {
      int i;
      #pragma omp parallel shared(a,b,n) private(i) {
        #pragma omp for
          for (i = 0; i < n; i++)
            a[i] = 1.0 / a[i];
          #pragma omp single
            a[0] = MIN( a[0], 1.0 );
          #pragma omp for nowait
          for (i = 0; i < n; i++)
          b[i] = b[i] / a[i];
       }
    }

Parent topic: OpenMP* Support