One more observation... I tried a third variation in which the test program still uses a single shared IOArray but each thread writes to different indices in the array. In this case I get good scaling with performance similar to the use of IOUArray. In detail, I made the following two changes to give each thread a disjoint set of indices to write to:<div>
<br></div><div>bunchOfKeys threadNum = take numElems $ zip (cycle $ indices numThreads threadNum) $ drop threadNum cyclicChars</div><div><br></div><div>and </div><div><br></div><div><div>indices :: Int -&gt; Int -&gt; [Int]</div>
<div>indices numThreads threadNum = </div><div>  let numixs      = arraySize `div` numThreads</div><div>      startIx     = numixs * threadNum</div><div>      allIndices  = [0..highestIndex]</div><div>  in take numixs $ drop startIx allIndices</div>
<div><br></div><div><br></div><div>--Andreas</div><br><div class="gmail_quote">On Tue, Aug 23, 2011 at 5:07 PM, Andreas Voellmy <span dir="ltr">&lt;<a href="mailto:andreas.voellmy@gmail.com">andreas.voellmy@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Thanks for the suggestions. I tried to add strictness in the following ways: <div><br></div><div>(1) Changing &quot;insertDAT a j c&quot; to &quot;insertDAT a j $! c&quot;</div>
<div>(2) Changing &quot;insertDAT a j c&quot; to &quot;deepseq c (insertDAT a j c)&quot;</div>
<div><br></div><div>I also used Int instead of Int32 throughout and changed the DAT data type to a newtype definition. These changes improved the performance slightly, but still, the multithreaded runs perform significantly worse than the single-threaded runs, by about the same amount (i.e. 0.5 seconds more for the 2 core run than for the 1 core run). </div>

<div><br></div><div>I used ghc 7.0.3 for the performance measurements I gave in my message. I&#39;ve also tried under 7.2.1, and I get basically the same behavior there.</div><div><br></div><div><font color="#888888">--Andreas</font><div>
<div></div><div class="h5"><br><br><div class="gmail_quote">
On Tue, Aug 23, 2011 at 4:38 PM, Johan Tibell <span dir="ltr">&lt;<a href="mailto:johan.tibell@gmail.com" target="_blank">johan.tibell@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

On Tue, Aug 23, 2011 at 10:04 PM, Andreas Voellmy<br>
<div>&lt;<a href="mailto:andreas.voellmy@gmail.com" target="_blank">andreas.voellmy@gmail.com</a>&gt; wrote:<br>
</div><div>&gt; data DAT = DAT (IOArray Int32 Char)<br>
<br>
</div>Try to make this a newtype instead. The data type adds a level of indirection.<br>
<div><br>
&gt;   do let p j c = insertDAT a j c &gt;&gt; lookupDAT a j &gt;&gt;= \v -&gt; v `pseq` return<br>
&gt; ()<br>
<br>
</div>You most likely want (insertDAT a j $! c) to make sure that the<br>
element is force, to avoid thunks building up in the array.<br>
<br>
&gt; -- Parameters<br>
&gt; arraySize :: Int32<br>
<br>
Int might work better than Int32. While they should behave the same on<br>
32-bit machines Int might have a few more rewrite rules that makes it<br>
optimize better.<br>
<font color="#888888"><br>
-- Johan<br>
</font></blockquote></div><br></div></div></div>
</blockquote></div><br></div>