monad-par-0.1: examples/parfib.hs
import Data.Int
import System.Environment
-- import Control.Monad.Par
import Control.Monad.ParElision
import GHC.Conc
type FibType = Int64
-- sequential version of the code
fib :: FibType -> FibType
fib 0 = 1
fib 1 = 1
fib x = fib (x-2) + fib (x-1) + 1
-- Basic, non-monadic parallel-fib:
parfib0 :: FibType -> FibType
parfib0 n | n < 2 = 1
parfib0 n = x `par` y `pseq` (x+y)
where
x = parfib0 (n-1)
y = parfib0 (n-2)
parfib1 :: FibType -> Par FibType
parfib1 n | n < 2 = return 1
parfib1 n =
do
xf <- spawn_$ parfib1 (n-1)
y <- parfib1 (n-2)
x <- get xf
return (x+y)
main = do args <- getArgs
let (version,size) =
case args of
[] -> ("monad",10)
[v,n] -> (v,read n)
case version of
"monad" -> do
putStrLn "Monad-par based version:"
print$ runPar$ parfib1 size
"sparks" -> do
putStrLn "Sparks-based, Non-monadic version:"
print$ parfib0 size
_ -> error$ "unknown version: "++version
{- On 4-core nehalem, 3.33ghz:
Non-monadic version, real/user time:
fib(40) 4 threads: 1.1s 4.4s
fib(42) 4 threads: 2.9s 11.6s 17GB allocated
SPARKS: 433784785 (290 converted, 280395620 pruned)
Monad-par version:
fib(38) non-threaded: 23.3s 23.1s
fib(38) 1 thread : 24.7s 24.5s
fib(38) 4 threads: 8.2s 31.3s
fib(40) 4 threads: 20.6s 78.6s 240GB allocated
For comparison, Cilkarts Cilk++:
fib(42) 4 threads: 3.029s 23.610s
Intel Cilk Plus:
fib(42) 4 threads: 4.212s 16.770s
-}