I&#39;m afraid without uniqueness or linear typing it would be hard to avoid.<br><br><div class="gmail_quote">2012/3/10 Thiago Negri <span dir="ltr">&lt;<a href="mailto:evohunz@gmail.com">evohunz@gmail.com</a>&gt;</span><br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I see. Thanks for the answers.<br>
<br>
Any data structure or source annotation that would prevent that?<br>
<br>
For example, if I try the same program to run on a<br>
[1..9999999999999999] list, I&#39;ll get an out of memory error for the<br>
single-threaded version. Any way to prevent it without declaring two<br>
different versions of &quot;list&quot;?<br>
<br>
<br>
2012/3/10 Anthony Cowley &lt;<a href="mailto:acowley@gmail.com">acowley@gmail.com</a>&gt;:<br>
<div class="HOEnZb"><div class="h5">&gt; From that profiling data, I think you&#39;re just seeing a decrease in sharing. With one thread, you create the list structure in memory: the first fold could consume it in-place, but the second fold is still waiting for its turn.  The list is built on the heap so the two folds can both refer to the same list.<br>


&gt;<br>
&gt; With two threads, GHC is being clever and inlining the definition you give for list, which is then optimized into two parallel loops. No list on the heap means there&#39;s not much for the GC to do.<br>
&gt;<br>
&gt; Sharing of index lists like this is a common source of problems. In particular, nested loops can make it even trickier to prevent sharing as there may not be an opportunity for parallel evaluation.<br>
&gt;<br>
&gt; Anthony<br>
&gt;<br>
&gt; On Mar 10, 2012, at 10:21 AM, Thiago Negri &lt;<a href="mailto:evohunz@gmail.com">evohunz@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt;&gt; Hi all.<br>
&gt;&gt;<br>
&gt;&gt; I wrote a very simple program to try out parallel Haskel and check how<br>
&gt;&gt; it would look like to make use of more than one core in this language.<br>
&gt;&gt;<br>
&gt;&gt; When I tried the program with RTS option -N1, total time shows it took<br>
&gt;&gt; 2.48 seconds to complete and around 65% of that time was taken by GC.<br>
&gt;&gt;<br>
&gt;&gt; Then I tried the same program with RTS options -N2 and total time<br>
&gt;&gt; decreased to 1.15 seconds as I expected a gain here. But what I didn&#39;t<br>
&gt;&gt; expect is the GC time to drop to 0%.<br>
&gt;&gt;<br>
&gt;&gt; I guess I&#39;m having trouble to understand the output of the RTS option -s.<br>
&gt;&gt; Can you enlighten me?<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; The source for the testing program:<br>
&gt;&gt;<br>
&gt;&gt;&gt; module Main where<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; import Data.List (foldl1&#39;)<br>
&gt;&gt;&gt; import Control.Parallel (par, pseq)<br>
&gt;&gt;&gt; import Control.Arrow ((&amp;&amp;&amp;))<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; f `parApp` (a, b) = a `par` (b `pseq` (f a b))<br>
&gt;&gt;&gt; seqApp = uncurry<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; main = print result<br>
&gt;&gt;&gt;  where result = (+) `parApp` minMax list<br>
&gt;&gt;&gt;        minMax = minlist &amp;&amp;&amp; maxlist<br>
&gt;&gt;&gt;        minlist = foldl1&#39; min<br>
&gt;&gt;&gt;        maxlist = foldl1&#39; max<br>
&gt;&gt;&gt;        list = [1..19999999]<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; The results on a Windows 7 64bits with an Intel Core 2 Duo, compiled<br>
&gt;&gt; with GHC from Haskell Platform:<br>
&gt;&gt;<br>
&gt;&gt; c:\tmp\hs&gt;par +RTS -s -N1<br>
&gt;&gt; par +RTS -s -N1<br>
&gt;&gt; 20000000<br>
&gt;&gt;     803,186,152 bytes allocated in the heap<br>
&gt;&gt;     859,916,960 bytes copied during GC<br>
&gt;&gt;     233,465,740 bytes maximum residency (10 sample(s))<br>
&gt;&gt;      30,065,860 bytes maximum slop<br>
&gt;&gt;             483 MB total memory in use (0 MB lost due to fragmentation)<br>
&gt;&gt;<br>
&gt;&gt;  Generation 0:  1523 collections,     0 parallel,  0.80s,  0.75s elapsed<br>
&gt;&gt;  Generation 1:    10 collections,     0 parallel,  0.83s,  0.99s elapsed<br>
&gt;&gt;<br>
&gt;&gt;  Parallel GC work balance: nan (0 / 0, ideal 1)<br>
&gt;&gt;<br>
&gt;&gt;                        MUT time (elapsed)       GC time  (elapsed)<br>
&gt;&gt;  Task  0 (worker) :    0.00s    (  0.90s)       0.00s    (  0.06s)<br>
&gt;&gt;  Task  1 (worker) :    0.00s    (  0.90s)       0.00s    (  0.00s)<br>
&gt;&gt;  Task  2 (bound)  :    0.86s    (  0.90s)       1.62s    (  1.69s)<br>
&gt;&gt;<br>
&gt;&gt;  SPARKS: 1 (0 converted, 0 pruned)<br>
&gt;&gt;<br>
&gt;&gt;  INIT  time    0.00s  (  0.00s elapsed)<br>
&gt;&gt;  MUT   time    0.86s  (  0.90s elapsed)<br>
&gt;&gt;  GC    time    1.62s  (  1.74s elapsed)<br>
&gt;&gt;  EXIT  time    0.00s  (  0.00s elapsed)<br>
&gt;&gt;  Total time    2.48s  (  2.65s elapsed)<br>
&gt;&gt;<br>
&gt;&gt;  %GC time      65.4%  (65.9% elapsed)<br>
&gt;&gt;<br>
&gt;&gt;  Alloc rate    936,110,032 bytes per MUT second<br>
&gt;&gt;<br>
&gt;&gt;  Productivity  34.6% of total user, 32.4% of total elapsed<br>
&gt;&gt;<br>
&gt;&gt; gc_alloc_block_sync: 0<br>
&gt;&gt; whitehole_spin: 0<br>
&gt;&gt; gen[0].sync_large_objects: 0<br>
&gt;&gt; gen[1].sync_large_objects: 0<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; c:\tmp\hs&gt;par +RTS -s -N2<br>
&gt;&gt; par +RTS -s -N2<br>
&gt;&gt; 20000000<br>
&gt;&gt;   1,606,279,644 bytes allocated in the heap<br>
&gt;&gt;          74,924 bytes copied during GC<br>
&gt;&gt;          28,340 bytes maximum residency (1 sample(s))<br>
&gt;&gt;          29,004 bytes maximum slop<br>
&gt;&gt;               2 MB total memory in use (0 MB lost due to fragmentation)<br>
&gt;&gt;<br>
&gt;&gt;  Generation 0:  1566 collections,  1565 parallel,  0.00s,  0.01s elapsed<br>
&gt;&gt;  Generation 1:     1 collections,     1 parallel,  0.00s,  0.00s elapsed<br>
&gt;&gt;<br>
&gt;&gt;  Parallel GC work balance: 1.78 (15495 / 8703, ideal 2)<br>
&gt;&gt;<br>
&gt;&gt;                        MUT time (elapsed)       GC time  (elapsed)<br>
&gt;&gt;  Task  0 (worker) :    0.00s    (  0.59s)       0.00s    (  0.00s)<br>
&gt;&gt;  Task  1 (worker) :    0.58s    (  0.59s)       0.00s    (  0.01s)<br>
&gt;&gt;  Task  2 (bound)  :    0.58s    (  0.59s)       0.00s    (  0.00s)<br>
&gt;&gt;  Task  3 (worker) :    0.00s    (  0.59s)       0.00s    (  0.00s)<br>
&gt;&gt;<br>
&gt;&gt;  SPARKS: 1 (1 converted, 0 pruned)<br>
&gt;&gt;<br>
&gt;&gt;  INIT  time    0.00s  (  0.00s elapsed)<br>
&gt;&gt;  MUT   time    1.15s  (  0.59s elapsed)<br>
&gt;&gt;  GC    time    0.00s  (  0.01s elapsed)<br>
&gt;&gt;  EXIT  time    0.00s  (  0.00s elapsed)<br>
&gt;&gt;  Total time    1.15s  (  0.61s elapsed)<br>
&gt;&gt;<br>
&gt;&gt;  %GC time       0.0%  (2.4% elapsed)<br>
&gt;&gt;<br>
&gt;&gt;  Alloc rate    1,391,432,695 bytes per MUT second<br>
&gt;&gt;<br>
&gt;&gt;  Productivity 100.0% of total user, 190.3% of total elapsed<br>
&gt;&gt;<br>
&gt;&gt; gc_alloc_block_sync: 90<br>
&gt;&gt; whitehole_spin: 0<br>
&gt;&gt; gen[0].sync_large_objects: 0<br>
&gt;&gt; gen[1].sync_large_objects: 0<br>
&gt;&gt;<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; Haskell-Cafe mailing list<br>
&gt;&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt;&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br>