Parallel forkOS does not work on ubuntu
Don Stewart
dons at galois.com
Tue Dec 9 15:47:42 EST 2008
hoangta:
> Hello everybody,
> I am following "A Tutorial on Parallel and Concurrent Programming in
> Haskell" and I have a problem with making Haskell to use my multi-cores
> (Core 2 Quad CPU).
> The Haskel version I used is GHC 6.10.1, for Haskell 98. I compile my
> below program with command: ghc --make -threaded -debug thread0.hs, and
> run with: thread0 +RTS -N4 while watching the cpu usage on another
> terminal (by: mpstat -P ALL 1 100), but the program uses only one core of
> my Ubuntu Linux.
> Do any of you know why or has any suggestions? Below is my program:
> import Control.Concurrent
> import Control.Concurrent.MVar
> fib :: Int -> Int
> fib 0 = 0
> fib 1 = 1
> fib n = fib (n-1) + fib (n-2)
> dowork =
> putStrLn ("fib 35 = " ++ (show (fib 35)))
> threadA :: MVar Int -> MVar Int -> MVar Int -> IO ()
> threadA valueToSendMVar valueToReadMVar valueToQuit
> = do
> -- some work
> dowork
> -- perform rendezvous
> putMVar valueToSendMVar 30 -- send value
> v <- takeMVar valueToReadMVar
> putStrLn ("result, fib 30 = " ++ (show v))
> dowork
> -- notify done
> putMVar valueToQuit 0 -- send value
> threadB :: MVar Int -> MVar Int -> MVar Int -> IO ()
> threadB valueToReceiveMVar valueToSendMVar valueToQuit
> = do
> -- some work
> dowork
> -- perform rendezvous by waiting
> z <- takeMVar valueToReceiveMVar
> putMVar valueToSendMVar (fib z)
> -- continue with other work
> dowork
> -- notify done
> putMVar valueToQuit 0 -- send value
> main :: IO ()
> main
> = do
> aQuitA <- newEmptyMVar
> aQuitB <- newEmptyMVar
> aMVar <- newEmptyMVar
> bMVar <- newEmptyMVar
> forkOS (threadA aMVar bMVar aQuitA )
> forkOS (threadB aMVar bMVar aQuitB )
> -- wait for threadA and threadB
> takeMVar aQuitA
> takeMVar aQuitB
> return ()
How about,
import Control.Parallel
import Control.Monad
import Text.Printf
cutoff = 35
fib' :: Int -> Integer
fib' 0 = 0
fib' 1 = 1
fib' n = fib' (n-1) + fib' (n-2)
fib :: Int -> Integer
fib n | n < cutoff = fib' n
| otherwise = r `par` (l `pseq` l + r)
where
l = fib (n-1)
r = fib (n-2)
main = forM_ [0..45] $ \i ->
printf "n=%d => %d\n" i (fib i)
Where:
$ ghc -O2 -threaded fib.hs --make
Linking fib ...
$ time ./fib +RTS -N2
n=0 => 0
n=1 => 1
n=2 => 1
n=3 => 2
n=4 => 3
...
n=43 => 433494437
n=44 => 701408733
n=45 => 1134903170
./fib 30 +RTS -N2 107.56s user 0.54s system 184% cpu 58.703 tota
More information about the Glasgow-haskell-users
mailing list