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