Programação multi-core em Haskell - Control.Parallel

Estou tentando aprender como usar oControl.Parallel módulo, mas acho que não entendi direito.

Estou tentando executar o seguinte código (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

Eu compilei isto com:

ghc -O2 --make -threaded fibs.hs

E então eu obtenho os seguintes resultados executando este programa (saída de um script Python que executa cada programa 100 vezes e retorna a média e o desvio padrão do tempo de execução):

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

Minhas perguntas são:

O que exatamente está acontecendo quando eu avalio:

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

Eu entendo que umpar b deve sugerir ao compilador sobre calcular a em paralelo com b e retornar b. ESTÁ BEM. Mas o que fazpseq Faz?

Por que vejo um aumento de desempenho tão pequeno? Eu estou correndo isso em um IntelCore 2 Máquina quádrupla. Eu esperaria que a execução com -N5 ou -N6 não fizesse uma diferença real no desempenho ou que o programa realmente começasse a ter um desempenho muito ruim. Mas por que não vejo melhora de N2 para -N3 e por que a melhora inicial é tão pequena?

questionAnswers(4)

yourAnswerToTheQuestion