Programowanie wielordzeniowe w Haskell - Control.Parallel

Próbuję nauczyć się korzystać zControl.Parallel moduł, ale myślę, że nie udało mi się.

Próbuję uruchomić następujący kod (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

Skompilowałem to z:

ghc -O2 --make -threaded fibs.hs

Następnie otrzymuję następujące wyniki wykonujące ten program (wyjście skryptu Pythona, który uruchamia każdy program 100 razy i zwraca średnie i standardowe odchylenie czasu wykonania):

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

Moje pytania to:

Co dokładnie dzieje się, gdy oceniam:

a `par` (b `pseq` (a + b))   ?

Rozumiem, że apar b ma wskazywać kompilatorowi na obliczenie a równolegle z b i zwrotem b. DOBRZE. Ale co robipseq robić?

Dlaczego widzę tak mały wzrost wydajności? Używam tego w InteluCore 2 Maszyna Quad. Spodziewałbym się, że uruchamianie z -N5 lub -N6 nie miałoby prawdziwej różnicy w wydajności lub że program zacząłby działać bardzo źle. Ale dlaczego nie widzę poprawy od -N2 do -N3 i dlaczego początkowa poprawa jest tak mała?

questionAnswers(4)

yourAnswerToTheQuestion