====== OpenMP in Fortran ======
OpenMP stellt eine einfache Möglichkeiten dar, Code zu parallelisieren. Dabei parallelisiert der Compiler automatisch Schleifen etc, mithilfe von mehreren Threads. 
===== Parallel Do =====
Eine Do-Schleife (also eine Zählschleife) lässt sich durch OpenMP parallelisieren, wenn die Zählvariable im Schleifenkörper nicht verändert wird. Bspw. ist es möglich folgende Schleife zu parallelisieren:
program main
  integer, parameter :: n = 1000000
  integer :: k
  integer,dimension(n) :: value
  
  do k=1, n, +1
    value(k) = k**k
  enddo
  
  write (*,*) (value(k), k=1, n)
end program
Hier werden also Quadratzahlen der Zahlen von 1 bis 1000000 berechnet. Nun geben wir dem Compiler zu verstehen, dass die do-Schleife parallel ausgeführt werden soll:
program main
  integer, parameter :: n = 1000000
  integer :: k
  integer,dimension(n) :: value
  
!$omp parallel do
  do k=1, n, +1
    value(k) = k**k
  enddo
!$omp end parallel do
  write (*,*) (value(k), k=1, n)
end program
Übersetzen wir den Code:
gfortran do_omp.f90 -fopenmp
Und führen aus, erhalten wir folgende Zeiten:
$ gfortran do.f90
$ time ./a.out > /dev/null
real	0m0.303s
user	0m0.289s
sys	0m0.011s
$ gfortran do_omp.f90 -fopenmp
$ time ./a.out > /dev/null
real	0m0.288s
user	0m0.354s
sys	0m0.013s
Eine Einschätzung, warum der Geschwindigkeitsgewinn so gering sein könnten, finden Sie unten.
===== Reduktion =====
Neben vielen weiteren Funktionen von OpenMP gibt es noch die Möglichkeit eine Reduktion anzugeben, oder Variablen privat pro Thread oder shared zu setzen. Hier wird eine Summe über alle Quadratzahlen berechnet:
program main
  integer, parameter :: n = 1000000
  integer :: k
  integer :: summe
  
!$omp parallel do reduction(+:summe) default(shared), private(k)
  do k=1, n, +1
    summe = summe + k**k
  enddo
!$omp end parallel do
  write (*,*) summe
end program
====== Warum sind die gezeigten Beispiele so langsam? ======
OpenMP arbeitet mit Threads, dh. aus dem Code, den Sie dem Compiler übergeben, erzeugt dieser Threads. Die Threaderzeugung benötigt eine Weile. Wenn also jeder Thread wenig Arbeit zu machen hat, dann überwiegt die Erzeugungszeit der Threads, gegenüber der Ersparnis der Berechnungszeit. Bei größeren Beispielen sollen Sie Laufzeitverringerungen bemerken.