<div dir="ltr">Could you post the code please?</div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jan 24, 2016 at 12:46 AM, Thomas Koster <span dir="ltr"><<a href="mailto:tkoster@gmail.com" target="_blank">tkoster@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi friends,<br>
<br>
Using Criterion, I have been running benchmarks to measure the<br>
relative performance of STM and MVars for some simple transactions<br>
that I expect will be typical in my application. I am using GHC 7.10.2<br>
and libraries as at Stackage LTS 3.2.<br>
<br>
I have found that STM is faster than MVars in all my benchmarks,<br>
without exception. This seems to go against accepted wisdom [1][2][3].<br>
I have not included my source code here to save space, but if you<br>
suspect that I am using MVars incorrectly, just say so and I will post<br>
my source code separately.<br>
<br>
I have two questions:<br>
<br>
1. When are MVars faster than STM? If the answer is "never", then when<br>
are MVars "better" than STM? (Choose your own definition of "better".)<br>
<br>
2. When given two capabilities (+RTS -N2), MVars are suddenly an order<br>
of magnitude slower than with just one capability. Why?<br>
<br>
<br>
For those who want details:<br>
<br>
My benchmark forks four Haskell threads. Each thread repeats a<br>
transaction that increments a shared counter many, many times. These<br>
transactions must be serialized. The counter is therefore highly<br>
contended. One version uses an MVar to store the counter in the<br>
obvious way. The other version uses a TVar instead.<br>
<br>
By the way, simply using "atomic-primops" to increment the counter<br>
won't do because the increment operation is actually a mock substitute<br>
for a more complex operation. I use the counter for my benchmarks<br>
because the real operation needs much more memory and I don't want the<br>
additional, unpredictable GC cost to affect my measurements.<br>
<br>
Typical measurements are:<br>
<br>
1 capability, using MVar: 37.30 ms<br>
1 capability, using TVar: 24.88 ms<br>
2 capabilities, using MVar: 1.564 s<br>
2 capabilities, using TVar: 80.09 ms<br>
4 capabilities, using MVar: 2.890 s<br>
4 capabilities, using TVar: 207.8 ms<br>
<br>
Notice that the MVar version suddenly slows by an order of magnitude<br>
when run with more than one capability. Why is this so? (This is<br>
question 2.)<br>
<br>
Despite the absolute time elapsed, I realize that the CPU usage<br>
characteristics of the two versions are also quite different. I<br>
realize that the MVar version interlocks the four threads so that only<br>
one capability is ever busy at a time, irrespective of the number of<br>
capabilities available, whereas the STM version allows up to four<br>
capabilities to be busy at once. However, I believe that the<br>
additional parallel transactions in the STM version would be mostly<br>
wasted, destined to be retried. Unless I am mistaken, this assumption<br>
appears to be consistent with the observation that the STM version<br>
with -N1 is the fastest of all. Despite all this wasted work by the<br>
thundering herd, the total CPU time (i.e. my power bill) for the STM<br>
version is still less than for the MVar version, because the MVar<br>
version so dramatically slow.<br>
<br>
Paradoxically, MVars seem to be the wrong tool for this job. So when<br>
are MVars faster than STM? (This is question 1.)<br>
<br>
[1] <a href="https://stackoverflow.com/questions/15439966/when-why-use-an-mvar-over-a-tvar" rel="noreferrer" target="_blank">https://stackoverflow.com/questions/15439966/when-why-use-an-mvar-over-a-tvar</a><br>
[2] <a href="https://www.reddit.com/r/haskell/comments/39ef3y/ioref_vs_mvar_vs_tvar_vs_tmvar/" rel="noreferrer" target="_blank">https://www.reddit.com/r/haskell/comments/39ef3y/ioref_vs_mvar_vs_tvar_vs_tmvar/</a><br>
[3] <a href="https://mail.haskell.org/pipermail/haskell-cafe/2014-January/112158.html" rel="noreferrer" target="_blank">https://mail.haskell.org/pipermail/haskell-cafe/2014-January/112158.html</a><br>
<br>
Thanks,<br>
Thomas Koster<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr">Chris Allen<br><div><span style="font-size:12.8000001907349px">Currently working onĀ </span><a href="http://haskellbook.com" target="_blank">http://haskellbook.com</a></div></div></div></div></div></div>
</div>