Thanks Don. Your fib program works well. It uses all four cores of my computer with +RTS -N4. But the Wombat.hs still does not work. It seems tricky to me.&nbsp;<br><br><div>Hoang</div><div><br><div class="gmail_quote">On Wed, Dec 10, 2008 at 4:47 AM, Don Stewart <span dir="ltr">&lt;<a href="mailto:dons@galois.com">dons@galois.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">hoangta:<br>
<div><div></div><div class="Wj3C7c">&gt; &nbsp; &nbsp;Hello everybody,<br>
&gt; &nbsp; &nbsp;I am following &quot;A Tutorial on Parallel and Concurrent Programming in<br>
&gt; &nbsp; &nbsp;Haskell&quot; and I have a problem with making Haskell to use my multi-cores<br>
&gt; &nbsp; &nbsp;(Core 2 Quad &nbsp;CPU).<br>
&gt; &nbsp; &nbsp;The Haskel version I used is GHC 6.10.1, for Haskell 98. I compile my<br>
&gt; &nbsp; &nbsp;below program with command: ghc --make -threaded -debug thread0.hs, and<br>
&gt; &nbsp; &nbsp;run with: thread0 +RTS -N4 while watching the cpu usage on another<br>
&gt; &nbsp; &nbsp;terminal (by: mpstat -P ALL 1 100), but the program uses only one core of<br>
&gt; &nbsp; &nbsp;my Ubuntu Linux.<br>
&gt; &nbsp; &nbsp;Do any of you know why or has any suggestions? Below is my program:<br>
<br>
&gt; &nbsp; &nbsp;import Control.Concurrent<br>
&gt; &nbsp; &nbsp;import Control.Concurrent.MVar<br>
&gt; &nbsp; &nbsp;fib :: Int -&gt; Int<br>
&gt; &nbsp; &nbsp;fib 0 = 0<br>
&gt; &nbsp; &nbsp;fib 1 = 1<br>
&gt; &nbsp; &nbsp;fib n = fib (n-1) + fib (n-2)<br>
&gt; &nbsp; &nbsp;dowork =<br>
&gt; &nbsp; &nbsp;putStrLn (&quot;fib 35 = &quot; ++ (show (fib 35)))<br>
&gt; &nbsp; &nbsp;threadA :: MVar Int -&gt; MVar Int -&gt; MVar Int -&gt; IO ()<br>
&gt; &nbsp; &nbsp;threadA valueToSendMVar valueToReadMVar valueToQuit<br>
&gt; &nbsp; &nbsp;= do<br>
&gt; &nbsp; &nbsp;-- some work<br>
&gt; &nbsp; &nbsp;dowork<br>
&gt; &nbsp; &nbsp;-- perform rendezvous<br>
&gt; &nbsp; &nbsp;putMVar valueToSendMVar 30 -- send value<br>
&gt; &nbsp; &nbsp;v &lt;- takeMVar valueToReadMVar<br>
&gt; &nbsp; &nbsp;putStrLn (&quot;result, fib 30 = &quot; ++ (show v))<br>
&gt; &nbsp; &nbsp;dowork<br>
&gt; &nbsp; &nbsp;-- notify done<br>
&gt; &nbsp; &nbsp;putMVar valueToQuit 0 -- send value<br>
&gt; &nbsp; &nbsp;threadB :: MVar Int -&gt; MVar Int -&gt; MVar Int -&gt; IO ()<br>
&gt; &nbsp; &nbsp;threadB valueToReceiveMVar valueToSendMVar valueToQuit<br>
&gt; &nbsp; &nbsp;= do<br>
&gt; &nbsp; &nbsp;-- some work<br>
&gt; &nbsp; &nbsp;dowork<br>
&gt; &nbsp; &nbsp;-- perform rendezvous by waiting<br>
&gt; &nbsp; &nbsp;z &lt;- takeMVar valueToReceiveMVar<br>
&gt; &nbsp; &nbsp;putMVar valueToSendMVar (fib z)<br>
&gt; &nbsp; &nbsp;-- continue with other work<br>
&gt; &nbsp; &nbsp;dowork<br>
&gt; &nbsp; &nbsp;-- notify done<br>
&gt; &nbsp; &nbsp;putMVar valueToQuit 0 -- send value<br>
&gt; &nbsp; &nbsp;main :: IO ()<br>
&gt; &nbsp; &nbsp;main<br>
&gt; &nbsp; &nbsp;= do<br>
&gt; &nbsp; &nbsp;aQuitA &lt;- newEmptyMVar<br>
&gt; &nbsp; &nbsp;aQuitB &lt;- newEmptyMVar<br>
&gt; &nbsp; &nbsp;aMVar &lt;- newEmptyMVar<br>
&gt; &nbsp; &nbsp;bMVar &lt;- newEmptyMVar<br>
&gt; &nbsp; &nbsp;forkOS (threadA aMVar bMVar aQuitA )<br>
&gt; &nbsp; &nbsp;forkOS (threadB aMVar bMVar aQuitB )<br>
&gt; &nbsp; &nbsp;-- wait for threadA and threadB<br>
&gt; &nbsp; &nbsp;takeMVar aQuitA<br>
&gt; &nbsp; &nbsp;takeMVar aQuitB<br>
&gt; &nbsp; &nbsp;return ()<br>
<br>
<br>
<br>
</div></div>How about,<br>
<br>
 &nbsp; &nbsp;import Control.Parallel<br>
 &nbsp; &nbsp;import Control.Monad<br>
 &nbsp; &nbsp;import Text.Printf<br>
<br>
 &nbsp; &nbsp;cutoff = 35<br>
<br>
 &nbsp; &nbsp;fib&#39; :: Int -&gt; Integer<br>
<div class="Ih2E3d"> &nbsp; &nbsp;fib&#39; 0 = 0<br>
 &nbsp; &nbsp;fib&#39; 1 = 1<br>
 &nbsp; &nbsp;fib&#39; n = fib&#39; (n-1) + fib&#39; (n-2)<br>
<br>
</div> &nbsp; &nbsp;fib :: Int -&gt; Integer<br>
 &nbsp; &nbsp;fib n | n &lt; cutoff = fib&#39; n<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| otherwise &nbsp;= r `par` (l `pseq` l + r)<br>
 &nbsp; &nbsp; where<br>
 &nbsp; &nbsp; &nbsp; &nbsp;l = fib (n-1)<br>
 &nbsp; &nbsp; &nbsp; &nbsp;r = fib (n-2)<br>
<br>
 &nbsp; &nbsp;main = forM_ [0..45] $ \i -&gt;<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printf &quot;n=%d =&gt; %d\n&quot; i (fib i)<br>
<br>
Where:<br>
<br>
<br>
 &nbsp; &nbsp;$ ghc -O2 -threaded fib.hs &nbsp;--make<br>
 &nbsp; &nbsp;Linking fib ...<br>
<br>
 &nbsp; &nbsp;$ time ./fib +RTS -N2<br>
 &nbsp; &nbsp;n=0 =&gt; 0<br>
 &nbsp; &nbsp;n=1 =&gt; 1<br>
 &nbsp; &nbsp;n=2 =&gt; 1<br>
 &nbsp; &nbsp;n=3 =&gt; 2<br>
 &nbsp; &nbsp;n=4 =&gt; 3<br>
 &nbsp; &nbsp;...<br>
 &nbsp; &nbsp;n=43 =&gt; 433494437<br>
 &nbsp; &nbsp;n=44 =&gt; 701408733<br>
 &nbsp; &nbsp;n=45 =&gt; 1134903170<br>
 &nbsp; &nbsp;./fib 30 +RTS -N2 &nbsp;107.56s user 0.54s system 184% cpu 58.703 tota<br>
</blockquote></div><br></div>