OK, I think I figured it out. If I understand correctly, I was just computing the input lists in parallel. The actual values were computed in the main thread lazily, later. This seems unintuitive to me. Shouldn&#39;t the merge functions force the evaluation of their arguments? Surely one wouldn&#39;t be calling them if they wanted to compute the results lazily.<br>
<br><div class="gmail_quote">On Sun, Mar 14, 2010 at 6:25 PM, Brock Peabody <span dir="ltr">&lt;<a href="mailto:brock.peabody@gmail.com">brock.peabody@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Hi,<br>I&#39;ve been trying to use Control.Concurrent.mergeIO to parallelize computation, and can&#39;t make it work.  In the sample program below, I expect the function &#39;parallelTest&#39; to be almost twice as fast as &#39;sequentialTest&#39;, and to compute its results in two threads, as implied by the documentation for mergeIO.  This is not what happens.  If I link my program with the option &#39;-threaded&#39;, the running process does have three threads.  If I run with the option &quot;+RTS -N2&quot;, the process will have 5 threads.  In no case does the process appear to be using more than one CPU, and in fact it is slower with the threading options turned on.<br>

<br>I&#39;m sure I am doing something obviously (to someone else) wrong. Any ideas?<br><br>I am running the latest version of Mac OSX on a core2 duo machine with 2 cores, using ghc version 6.10.4.<br><br>Cheers, Brock<br>

<br>My test program follows:<br><br>{-# OPTIONS_GHC -fglasgow-exts #-}<br>module Main where<br><br>import Control.Concurrent<br>import Random<br><br>doSum :: RandomGen g =&gt; g -&gt; Int -&gt; Integer<br>doSum g count<br>

  = let runner curG sum numDone<br>          | numDone == count = sum<br>          | otherwise<br>              = let (newNum :: Integer, newG) = random curG<br>                    newSum = sum + newNum<br>                    newNumDone = numDone + 1<br>

                in ((runner $! newG) $! newSum) $! newNumDone<br>    in runner g 0 0<br><br>sequentialTest<br>  = do let gen = mkStdGen 0<br>           (g0,g1) = split gen<br>           count = 10000000<br>           sum0 = doSum g0 count<br>

           sum1 = doSum g1 count<br>           total = sum0 + sum1<br>       putStrLn $ &quot;total: &quot; ++ show total<br><br>parallelTest<br>  = do let gen = mkStdGen 0<br>           (g0,g1) = split gen<br>           count = 10000000<br>

           sum0 = doSum g0 count<br>           sum1 = doSum g1 count<br>       [res0, res1] &lt;- mergeIO [sum0] [sum1]<br>       let total = res0 + res1<br>       putStrLn $ &quot;total: &quot; ++ show total<br>main<br>
  = parallelTest<br>
</blockquote></div><br>