Parallele Algoritmen mit Haskell

In der funktionalen Programmiersprache Haskell gibt es eine sehr einfache Möglichkeit der Parallelisierung. Betrachte die folgende naive Implementierung der Fibonacci-Funktion.

fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

Diese Implementierung hat eine exponentielle Laufzeit und müsste eigentlich verbessert werden. Aber hier ist es so gewollt, denn wir benötigen eine langlaufende Funktion.

In Haskell gibt es zwei Operatoren, die zur Parallelisierung verwendet werden: pseq und par.

par erscheint anfangs etwas merkwürdig, aber Haskell hat eine Lazy-Auswertungsstrategie und das Ergebnis von a kann ja auch später weiterverwendet werden.

Ausgestattet mit diesen beiden Operationen ist eine Parallelisierung von fib sehr einfach.

parfib n
  | n < 11    = fib n                         -- For small values of n we use the sequential version
  | otherwise = f1 `par` (f2 `pseq` (f1+f2))  -- calculate f1 and f2 in parallel, return the sum as the result
where
  f1 = parfib (n-1)
  f2 = parfib (n-2)

Erst werden parallel f1 und f2 berechnet und anschließend werden sie addiert.

Das Programm muss mit der Option -threaded kompiliert werden.

ghc -O3 -threaded --make -o parfib ParFib.hs

Die Anzahl der Threads wird zur Laufzeit mit -N angegeben.

./parfib +RTS -N7 -RTS

Mit einem Intel Core i7 920 gab es für n=38 einen Speedup von 4.13. Dieser Prozessor hat vier physikalische Kerne, also ist die Parallelisierung effektiv und effizient.

Copyright © 2007-2012 Jörn Dinkla. All rights reserved.

Valid XHTML 1.0 Strict Valid CSS! Firebug - Web Development Evolved
Last modified: