Ich versuche zu lernen, wie man das Control.Parallel
-Modul zu verwenden, aber ich denke, dass ich es nicht richtig verstanden habe.Multicore-Programmierung in Haskell - Control.Parallel
Ich versuche, den folgenden Code auszuführen (fibs.hs).
import Control.Parallel
fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = p `par` (q `pseq` (p + q))
where
p = fib (n-1)
q = fib (n-2)
main = print $ fib 30
ich zusammengestellt dies mit:
ghc -O2 --make -threaded fibs.hs
Und dann bekomme ich folgende Ergebnisse dieses Programm (Ausgabe eines Python-Skript ausgeführt wird, dass jedes Programm 100 mal läuft und gibt den Mittelwert und Standardabweichung von der Ausführungszeit):
./fibs +RTS -N1 -> avg= 0.060203 s, deviation = 0.004112 s
./fibs +RTS -N2 -> avg= 0.052335 s, deviation = 0.006713 s
./fibs +RTS -N3 -> avg= 0.052935 s, deviation = 0.006183 s
./fibs +RTS -N4 -> avg= 0.053976 s, deviation = 0.007106 s
./fibs +RTS -N5 -> avg= 0.055227 s, deviation = 0.008598 s
./fibs +RTS -N6 -> avg= 0.055703 s, deviation = 0.006537 s
./fibs +RTS -N7 -> avg= 0.058327 s, deviation = 0.007526 s
Meine Fragen sind:
Was genau passiert, wenn ich beurteilen:
a `par` (b `pseq` (a + b)) ?
Ich verstehe, dass ein
par
b soll der Compiler über die Berechnung ein parallel zu b und das Rück b andeuten. OK. Aber was machtpseq
?Warum sehe ich eine so kleine Leistungssteigerung? Ich führe dies in einem Intel Core 2 Quad-Rechner. Ich würde erwarten, dass das Laufen mit -N5 oder -N6 keinen wirklichen Unterschied in der Leistung machen würde oder dass das Programm tatsächlich sehr schlecht arbeiten würde. Aber warum sehe ich keine Verbesserung von -N2 zu -N3 und warum ist die anfängliche Verbesserung so gering?
Haskell gleicht nicht automatisch Funken aus, um die beste Leistung zu erhalten? – Chuck
Es gleicht automatisch Threads ab. Die Laufzeit verfügt über Warteschlangen nicht evaluierter Ausdrücke (Sparks), die bei abnehmender Arbeitsauslastung in Threads konvertiert werden. Es liegt immer noch an Ihnen, nicht zu viele Funken zu erzeugen (und somit Zeit zu verschwenden, um Funkenwarteschlangen zu füllen) –