OpenMP

Shared-memory parallelism via compiler directives (!$omp).

Shared-memory parallelism via compiler directives (!$omp). Compile with -fopenmp (gfortran), -qopenmp (ifx).

28.1 Parallel loops

program omp_demo
  use omp_lib
  implicit none
  integer, parameter :: n = 10000000
  real(8), allocatable :: a(:), b(:)
  real(8) :: total
  integer :: i

  allocate(a(n), b(n))
  b = 1.0d0

  !$omp parallel do
  do i = 1, n
    a(i) = 2.0d0 * b(i) + sin(dble(i))
  end do
  !$omp end parallel do

  total = 0.0d0
  !$omp parallel do reduction(+:total)
  do i = 1, n
    total = total + a(i)
  end do
  !$omp end parallel do

  print *, "threads:", omp_get_max_threads(), " total:", total
end program omp_demo
gfortran -O2 -fopenmp omp_demo.f90 -o omp_demo
OMP_NUM_THREADS=8 ./omp_demo

28.2 Data-sharing clauses

one copy shared by all threads (default for most variables) each thread has its own uninitialized copy (loop index is private automatically) private, initialized from the original value from the last iteration copied out combine per-thread partial results (+, *, max, min, .and., .or., iand,...) force explicit scoping (recommended)

28.3 More constructs

Schedules: static, dynamic, guided, auto, runtime. Timing: omp_get_wtime().

!$omp parallel private(tid)
  tid = omp_get_thread_num()
  !$omp single
    print *, "team size", omp_get_num_threads()
  !$omp end single
  !$omp critical
    counter = counter + 1                 ! one thread at a time
  !$omp end critical
  !$omp atomic
    hits = hits + 1                       ! cheap atomic update
  !$omp barrier
  !$omp master
    print *, "master only"
  !$omp end master
!$omp end parallel

!$omp parallel do collapse(2) schedule(dynamic, 16)
do j = 1, m
  do i = 1, n
    c(i, j) = work(i, j)
  end do
end do

!$omp parallel sections
  !$omp section
    call task_a()
  !$omp section
    call task_b()
!$omp end parallel sections

!$omp parallel
  !$omp single
    !$omp task
      call process(left)
    !$omp end task
    !$omp task
      call process(right)
    !$omp end task
    !$omp taskwait
  !$omp end single
!$omp end parallel

!$omp simd
do i = 1, n
  y(i) = a * x(i) + y(i)
end do

!$omp workshare                          ! parallelize array syntax
  a = b + c
!$omp end workshare

28.4 Common pitfalls

Race conditions (forgetting private/reduction), false sharing, excessive synchronization, load imbalance, nested parallelism surprises, non-thread-safe save variables in called procedures.