<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Apr 22, 2013 at 2:37 PM, Sanne Grinovero <span dir="ltr">&lt;<a href="mailto:sanne@infinispan.org" target="_blank">sanne@infinispan.org</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">We also have been toying with the idea to hash each key only once,<br>
instead of both with the consistent hash (to assign the node owner)<br>
and once in the CHM backing the datacontainer.<br>
I doubt we need the datacontainer to implement Map at all, but at<br>
least if we go this way we don&#39;t want the hash to be affected by the<br>
VM instance or different nodes won&#39;t agree on the expected owner ;-)<br>
<br></blockquote><div><br></div><div></div><div>For consistent hashing it would probably be better to cache the hash after applying MurmurHash to it anyway. So we could in theory hack our CHMV8 to use a cached hash code computed with MurmurHash and a cluster-specific salt.<br>

<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Also there where reports of it having a very bad impact on<br>
performance, I&#39;m not sure if they where resolved yet, or are going to<br>
be resolved at all as it was important for security reasons.<br>
<div class=""><div class="h5"><br></div></div></blockquote><div><br>I suspect most of the performance impact came from no longer using the cached hash code in the String class. And since String.hashCode() isn&#39;t allowed to change, that isn&#39;t going to change any time soon.<br>

<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class=""><div class="h5">
<br>
On 22 April 2013 12:19, Dan Berindei &lt;<a href="mailto:dan.berindei@gmail.com">dan.berindei@gmail.com</a>&gt; wrote:<br>
&gt; Right. If we have anywhere a map that&#39;s initialized from a single thread and<br>
&gt; then accessed only for reading from many threads, it probably makes sense to<br>
&gt; use a HashMap and wrap it in an UnmodifiableMap. But if it can be written<br>
&gt; from multiple threads as well, I think we should use a CHMV8.<br>
&gt;<br>
&gt; BTW, the HashMap implementation in OpenJDK 1.7 seems to have some<br>
&gt; anti-collision features (a VM-dependent hash code generator for Strings),<br>
&gt; but our version of CHMV8 doesn&#39;t. Perhaps we need to upgrade to the latest<br>
&gt; CHMV8 version?<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; On Fri, Apr 19, 2013 at 4:32 PM, David M. Lloyd &lt;<a href="mailto:david.lloyd@redhat.com">david.lloyd@redhat.com</a>&gt;<br>
&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; On 04/19/2013 08:22 AM, Sanne Grinovero wrote:<br>
&gt;&gt; &gt; On 19 April 2013 13:52, David M. Lloyd &lt;<a href="mailto:david.lloyd@redhat.com">david.lloyd@redhat.com</a>&gt; wrote:<br>
&gt;&gt; &gt;&gt; On 04/19/2013 05:17 AM, Sanne Grinovero wrote:<br>
&gt;&gt; &gt;&gt;&gt; On 19 April 2013 11:10, Dan Berindei &lt;<a href="mailto:dan.berindei@gmail.com">dan.berindei@gmail.com</a>&gt; wrote:<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero<br>
&gt;&gt; &gt;&gt;&gt;&gt; &lt;<a href="mailto:sanne@infinispan.org">sanne@infinispan.org</a>&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; wrote:<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; On 19 April 2013 10:37, Dan Berindei &lt;<a href="mailto:dan.berindei@gmail.com">dan.berindei@gmail.com</a>&gt; wrote:<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; Testing mixed read/write performance with capacity 100000, keys<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; 300000,<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; concurrency level 32, threads 12, read:write ratio 99:1<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; Container CHM           Ops/s 5178894.77  Gets/s 5127105.82  Puts/s<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; 51788.95  HitRatio      86.23  Size     177848  stdDev   60896.42<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; Container CHMV8         Ops/s 5768824.37  Gets/s 5711136.13  Puts/s<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; 57688.24  HitRatio      84.72  Size     171964  stdDev   60249.99<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; Nice, thanks.<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; The test is probably limited by the 1% writes, but I think it does<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; show<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; that<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; reads in CHMV8 are not slower than reads in OpenJDK7&#39;s CHM.<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; I haven&#39;t measured it, but the memory footprint should also be<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; better,<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; because it doesn&#39;t use segments any more.<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level,<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; but<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; we<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; could definitely do a pure read test with a HashMap to see how big<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; the<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;&gt; performance difference is.<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; By copy-on-write I didn&#39;t mean on the single elements, but on the<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; whole map instance:<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; private volatile HashMap configuration;<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; synchronized addConfigurationProperty(String, String) {<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;        HashMap newcopy = new HashMap( configuration ):<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;        newcopy.put(..);<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;        configuration = newcopy;<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; }<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; Of course that is never going to scale for writes, but if writes<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; stop<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; at runtime after all services are started I would expect that the<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; simplicity of the non-threadsafe HashMap should have some benefit<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; over<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt; CHM{whatever}, or it would have been removed already?<br>
&gt;&gt; &gt;&gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt;&gt; Right, we should be able to tell whether that&#39;s worth doing with a<br>
&gt;&gt; &gt;&gt;&gt;&gt; pure read<br>
&gt;&gt; &gt;&gt;&gt;&gt; test with a CHMV8 and a HashMap :)<br>
&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt; IFF you find out CHMV8 is as good as HashMap for read only, you have<br>
&gt;&gt; &gt;&gt;&gt; two options:<br>
&gt;&gt; &gt;&gt;&gt;    - ask the JDK team to drop the HashMap code as it&#39;s no longer<br>
&gt;&gt; &gt;&gt;&gt; needed<br>
&gt;&gt; &gt;&gt;&gt;    - fix your benchmark :-P<br>
&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt; In other words, I&#39;d consider it highly surprising and suspicious<br>
&gt;&gt; &gt;&gt;&gt; (still interesting though!)<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; It&#39;s not as surprising as you think.  On x86, volatile reads are the<br>
&gt;&gt; &gt;&gt; same as regular reads (not counting some possible reordering magic).<br>
&gt;&gt; &gt;&gt; So<br>
&gt;&gt; &gt;&gt; if a CHM read is a hash, an array access, and a list traversal, and so<br>
&gt;&gt; &gt;&gt; is HM (and I believe this is true though I&#39;d have to review the code<br>
&gt;&gt; &gt;&gt; again to be sure), I&#39;d expect very similar execution performance on<br>
&gt;&gt; &gt;&gt; read.  I think some of the anti-collision features in V8 might come<br>
&gt;&gt; &gt;&gt; into<br>
&gt;&gt; &gt;&gt; play under some circumstances though which might affect performance in<br>
&gt;&gt; &gt;&gt; a<br>
&gt;&gt; &gt;&gt; negative way (wrt the constant big-O component) but overall in a<br>
&gt;&gt; &gt;&gt; positive way (by turning the linear big-O component into a logarithmic<br>
&gt;&gt; &gt;&gt; one).<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Thanks David. I know about the cost of a volatile read, what I&#39;m<br>
&gt;&gt; &gt; referring to<br>
&gt;&gt; &gt; is that I would expect the non-concurrent Maps to generally contain some<br>
&gt;&gt; &gt; simpler code than a conccurrent one. If this was not the case,<br>
&gt;&gt; &gt; why would any JDK team maintain two different implementations?<br>
&gt;&gt; &gt; That&#39;s why I would consider it surprising if it turned out that the<br>
&gt;&gt; &gt; CHMV8 was<br>
&gt;&gt; &gt; superior over a regular one on all fronts: there certainly is some<br>
&gt;&gt; &gt; scenario in which the regular one would be a more appropriate choice,<br>
&gt;&gt; &gt; which directly proofs that blindly replacing all usages in a large<br>
&gt;&gt; &gt; project<br>
&gt;&gt; &gt; is not optimal. Of course, it might be close to optimal..<br>
&gt;&gt;<br>
&gt;&gt; You are right, it is not superior on all fronts.  It is definitely<br>
&gt;&gt; similar in terms of read, but writes will have a substantially higher<br>
&gt;&gt; cost, involving (at the very least) multiple volatile writes which are<br>
&gt;&gt; orders of magnitude more expensive than normal writes (on Intel they<br>
&gt;&gt; have the costly impact of memory fence instructions).  So I don&#39;t think<br>
&gt;&gt; anyone will want to drop HashMap any time soon. :-)<br>
&gt;&gt;<br>
&gt;&gt; --<br>
&gt;&gt; - DML<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; infinispan-dev mailing list<br>
&gt;&gt; <a href="mailto:infinispan-dev@lists.jboss.org">infinispan-dev@lists.jboss.org</a><br>
&gt;&gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; infinispan-dev mailing list<br>
&gt; <a href="mailto:infinispan-dev@lists.jboss.org">infinispan-dev@lists.jboss.org</a><br>
&gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
_______________________________________________<br>
infinispan-dev mailing list<br>
<a href="mailto:infinispan-dev@lists.jboss.org">infinispan-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
</div></div></blockquote></div><br></div></div>