Re: [infinispan-dev] CHM or CHMv8?
Just a heads up on this. As mentioned in another email, I've created a CHMv8 version called EquivalentCHMv8 which allows equals/hashCode/toString calls on keys/values to be done via the new Equivalence interface, which allows even arrays to be used as key/values. I originally planned to keep both CHMv8 and EquivalentCHMv8, but as Manik already suggested in another email, we should just keep EquivalentCHMv8. The changes are fairly minimal compared to CHMv8. So, in case anyone is itching to start on 3022 and 3023, hold on for a few days while I finish the work to include EquivalentCHMv8. Cheers, On Apr 19, 2013, at 2:16 PM, Manik Surtani msurt...@redhat.com wrote: Ok, I've created https://issues.jboss.org/browse/ISPN-3022 In fact, we should also re-implement the BoundedConcurrentHashMap - the basis for LIRS and LRU eviction algorithms - to use techniques similar to CHMv8 rather than the old segment-based approach. https://issues.jboss.org/browse/ISPN-3023 Anyone has a few spare cycles - and is really good with complex concurrency code - want to take this on? ;) - M On 19 Apr 2013, at 09:06, Manik Surtani msurt...@redhat.com wrote: On 19 Apr 2013, at 05:07, Sanne Grinovero sa...@infinispan.org wrote: Why not. Only doubt I'd have is that other usages of the CHM are - I guess - services registry and similar configuration tools, for which write performance is irrelevant: your test measured puts, are there drawbacks on gets or memory usage? See the original announcement on concurrency-interest by Doug Lea, and the subsequent comments. The design is up here too. One of the goals was to drastically reduce memory usage with CHMv8. http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/8140 Interestingly, Netty uses a backported CHMv8 as well - apparently inspired by our inclusion of it in Infinispan. ;) https://github.com/netty/netty/issues/1052 -M -- Manik Surtani ma...@jboss.org twitter.com/maniksurtani Platform Architect, JBoss Data Grid http://red.ht/data-grid -- Manik Surtani ma...@jboss.org twitter.com/maniksurtani Platform Architect, JBoss Data Grid http://red.ht/data-grid ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev -- Galder Zamarreño gal...@redhat.com twitter.com/galderz Project Lead, Escalante http://escalante.io Engineer, Infinispan http://infinispan.org ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
On Apr 22, 2013, at 1:37 PM, Sanne Grinovero sa...@infinispan.org wrote: We also have been toying with the idea to hash each key only once, instead of both with the consistent hash (to assign the node owner) and once in the CHM backing the datacontainer. ^ With the new EquivalentCHMv8, I think we can make this happen quite easily, cos we provide a function that is used to calculate the hash of an object. Hence, we can think of a way to plug what you suggest there. I doubt we need the datacontainer to implement Map at all, but at least if we go this way we don't want the hash to be affected by the VM instance or different nodes won't agree on the expected owner ;-) Also there where reports of it having a very bad impact on performance, I'm not sure if they where resolved yet, or are going to be resolved at all as it was important for security reasons. On 22 April 2013 12:19, Dan Berindei dan.berin...@gmail.com wrote: Right. If we have anywhere a map that's initialized from a single thread and then accessed only for reading from many threads, it probably makes sense to use a HashMap and wrap it in an UnmodifiableMap. But if it can be written from multiple threads as well, I think we should use a CHMV8. BTW, the HashMap implementation in OpenJDK 1.7 seems to have some anti-collision features (a VM-dependent hash code generator for Strings), but our version of CHMV8 doesn't. Perhaps we need to upgrade to the latest CHMV8 version? On Fri, Apr 19, 2013 at 4:32 PM, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 08:22 AM, Sanne Grinovero wrote: On 19 April 2013 13:52, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 05:17 AM, Sanne Grinovero wrote: On 19 April 2013 11:10, Dan Berindei dan.berin...@gmail.com wrote: On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero sa...@infinispan.org wrote: On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Right, we should be able to tell whether that's worth doing with a pure read test with a CHMV8 and a HashMap :) IFF you find out CHMV8 is as good as HashMap for read only, you have two options: - ask the JDK team to drop the HashMap code as it's no longer needed - fix your benchmark :-P In other words, I'd consider it highly surprising and suspicious (still interesting though!) It's not as surprising as you think. On x86, volatile reads are the same as regular reads (not counting some possible reordering magic). So if a CHM read is a hash, an array access, and a list traversal, and so is HM (and I believe this is true though I'd have to review the code again to be sure), I'd expect very similar execution performance on read. I think some of the anti-collision features in V8 might come into play under some circumstances though which might affect performance in a negative way (wrt the constant big-O component) but overall in a positive way (by turning the linear big-O component into a logarithmic one). Thanks David. I know about the cost of a volatile read, what I'm referring to is that I would expect the non-concurrent Maps to generally contain some simpler code than a conccurrent one. If this was not the case, why would any JDK team maintain two different implementations? That's why I would consider it surprising if it turned out that the CHMV8 was superior over a regular one on all fronts: there certainly is some scenario in which the regular one would be a more appropriate choice, which directly proofs that blindly replacing
Re: [infinispan-dev] CHM or CHMv8?
On Apr 22, 2013, at 2:33 PM, David M. Lloyd david.ll...@redhat.com wrote: AFAIK the JDK team is looking at dropping alternative hashing for strings and instead going with the comparator-based collision resolution once a bucket reaches a certain size. I'm not sure how this is expected to work for a map with multiple key types though. ^ Hmmm, I'm pretty sure I've seen something similar in CHMv8. Once it reaches certain size, tree-based bins are used, which check whether the entries are Comparable. In fact, I've accomodated this into Equivalence interface, so that we can provide a way to define whether a given key or value is comparable, i.e. for arrays. Cheers, On 04/22/2013 06:19 AM, Dan Berindei wrote: Right. If we have anywhere a map that's initialized from a single thread and then accessed only for reading from many threads, it probably makes sense to use a HashMap and wrap it in an UnmodifiableMap. But if it can be written from multiple threads as well, I think we should use a CHMV8. BTW, the HashMap implementation in OpenJDK 1.7 seems to have some anti-collision features (a VM-dependent hash code generator for Strings), but our version of CHMV8 doesn't. Perhaps we need to upgrade to the latest CHMV8 version? On Fri, Apr 19, 2013 at 4:32 PM, David M. Lloyd david.ll...@redhat.com mailto:david.ll...@redhat.com wrote: On 04/19/2013 08:22 AM, Sanne Grinovero wrote: On 19 April 2013 13:52, David M. Lloyd david.ll...@redhat.com mailto:david.ll...@redhat.com wrote: On 04/19/2013 05:17 AM, Sanne Grinovero wrote: On 19 April 2013 11:10, Dan Berindei dan.berin...@gmail.com mailto:dan.berin...@gmail.com wrote: On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero sa...@infinispan.org mailto:sa...@infinispan.org wrote: On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com mailto:dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Right, we should be able to tell whether that's worth doing with a pure read test with a CHMV8 and a HashMap :) IFF you find out CHMV8 is as good as HashMap for read only, you have two options: - ask the JDK team to drop the HashMap code as it's no longer needed - fix your benchmark :-P In other words, I'd consider it highly surprising and suspicious (still interesting though!) It's not as surprising as you think. On x86, volatile reads are the same as regular reads (not counting some possible reordering magic). So if a CHM read is a hash, an array access, and a list traversal, and so is HM (and I believe this is true though I'd have to review the code again to be sure), I'd expect very similar execution performance on read. I think some of the anti-collision features in V8 might come into play under some circumstances though which might affect performance in a negative way (wrt the constant big-O component) but overall in a positive way (by turning the linear big-O component into a logarithmic one). Thanks David. I know about the cost of a volatile read, what I'm referring to is that I would expect the non-concurrent Maps to generally contain some simpler code than a conccurrent one. If this was not the case, why would any JDK team maintain two different implementations? That's why I would consider it surprising if it turned out that the CHMV8 was superior over a regular one on all fronts: there certainly is some scenario in which the regular one would be a more appropriate choice, which directly proofs that
Re: [infinispan-dev] CHM or CHMv8?
On Apr 22, 2013, at 3:09 PM, Dan Berindei dan.berin...@gmail.com wrote: On Mon, Apr 22, 2013 at 2:37 PM, Sanne Grinovero sa...@infinispan.org wrote: We also have been toying with the idea to hash each key only once, instead of both with the consistent hash (to assign the node owner) and once in the CHM backing the datacontainer. I doubt we need the datacontainer to implement Map at all, but at least if we go this way we don't want the hash to be affected by the VM instance or different nodes won't agree on the expected owner ;-) 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. ^ Rather than hacking CHMv8, better to provide an Equivalence function (which CHMv8 will have an instance variable of) for the keys which keeps the cache of hashes or something… once that work is committed, we can discuss further :) Also there where reports of it having a very bad impact on performance, I'm not sure if they where resolved yet, or are going to be resolved at all as it was important for security reasons. 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't allowed to change, that isn't going to change any time soon. On 22 April 2013 12:19, Dan Berindei dan.berin...@gmail.com wrote: Right. If we have anywhere a map that's initialized from a single thread and then accessed only for reading from many threads, it probably makes sense to use a HashMap and wrap it in an UnmodifiableMap. But if it can be written from multiple threads as well, I think we should use a CHMV8. BTW, the HashMap implementation in OpenJDK 1.7 seems to have some anti-collision features (a VM-dependent hash code generator for Strings), but our version of CHMV8 doesn't. Perhaps we need to upgrade to the latest CHMV8 version? On Fri, Apr 19, 2013 at 4:32 PM, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 08:22 AM, Sanne Grinovero wrote: On 19 April 2013 13:52, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 05:17 AM, Sanne Grinovero wrote: On 19 April 2013 11:10, Dan Berindei dan.berin...@gmail.com wrote: On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero sa...@infinispan.org wrote: On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Right, we should be able to tell whether that's worth doing with a pure read test with a CHMV8 and a HashMap :) IFF you find out CHMV8 is as good as HashMap for read only, you have two options: - ask the JDK team to drop the HashMap code as it's no longer needed - fix your benchmark :-P In other words, I'd consider it highly surprising and suspicious (still interesting though!) It's not as surprising as you think. On x86, volatile reads are the same as regular reads (not counting some possible reordering magic). So if a CHM read is a hash, an array access, and a list traversal, and so is HM (and I believe this is true though I'd have to review the code again to be sure), I'd expect very similar execution performance on read. I think some of the anti-collision features in V8 might come into play under some circumstances though which might affect
Re: [infinispan-dev] CHM or CHMv8?
On 25 April 2013 11:51, Galder Zamarreño gal...@redhat.com wrote: On Apr 22, 2013, at 3:09 PM, Dan Berindei dan.berin...@gmail.com wrote: On Mon, Apr 22, 2013 at 2:37 PM, Sanne Grinovero sa...@infinispan.org wrote: We also have been toying with the idea to hash each key only once, instead of both with the consistent hash (to assign the node owner) and once in the CHM backing the datacontainer. I doubt we need the datacontainer to implement Map at all, but at least if we go this way we don't want the hash to be affected by the VM instance or different nodes won't agree on the expected owner ;-) 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. ^ Rather than hacking CHMv8, better to provide an Equivalence function (which CHMv8 will have an instance variable of) for the keys which keeps the cache of hashes or something… once that work is committed, we can discuss further :) +1 to use your cool implementation. Don't like too much the sound of cache the hashes or something, I didn't actually look at the code, but from gut feeling I would hope the Equivalence function to be stateless? We might be able to pass the to-be-reused hash as a parameter in primitive form. Sanne ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
On 25 Apr 2013, at 11:41, Galder Zamarreño gal...@redhat.com wrote: So, in case anyone is itching to start on 3022 and 3023, hold on for a few days while I finish the work to include EquivalentCHMv8. 3022 is already in. The patch was trivial - change a default value in ConcurrentMapFactory. Once you finish EquivalentCHMv8, again, all you need to do is change ConcurrentMapFactory again to use EquivalentCHMv8 instead of CHMv8. As a side point, as you implement EquivalentCHMv8, could you make sure it is based on the latest CHMv8 impl from jsr166e: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/ConcurrentHashMapV8.java?revision=1.100view=markup We should also include, in the comments, what revision of jsr166e's implementation we're based on (e.g., 1.100 in the link above). - M -- Manik Surtani ma...@jboss.org twitter.com/maniksurtani Platform Architect, JBoss Data Grid http://red.ht/data-grid ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
On 25 Apr 2013, at 12:49, Dan Berindei wrote: Yeah, I don't think you could extract the hash from the cache of hashes without computing the hash in the first place... My idea was to wrap the key in a KeyWithHash object and cache the hash there (since we're looking up the same key in a lot of maps during a single invocation). My understanding of the problem Sanne tried to solve is the calculation of the hash of a key several times, in multiple interceptors, during a single operation/transaction. I don't think we should take it as far as keeping the hash together with the key. Also this is an optimisation so we shouldn't go out of our way in order to implement it. Sorry Galder, I forgot about your patch, but I still think we'd need a wrapper for keys in order to cache the hash code even if we could define an Equivalence function. Cheers, -- Mircea Markus Infinispan lead (www.infinispan.org) ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
Right. If we have anywhere a map that's initialized from a single thread and then accessed only for reading from many threads, it probably makes sense to use a HashMap and wrap it in an UnmodifiableMap. But if it can be written from multiple threads as well, I think we should use a CHMV8. BTW, the HashMap implementation in OpenJDK 1.7 seems to have some anti-collision features (a VM-dependent hash code generator for Strings), but our version of CHMV8 doesn't. Perhaps we need to upgrade to the latest CHMV8 version? On Fri, Apr 19, 2013 at 4:32 PM, David M. Lloyd david.ll...@redhat.comwrote: On 04/19/2013 08:22 AM, Sanne Grinovero wrote: On 19 April 2013 13:52, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 05:17 AM, Sanne Grinovero wrote: On 19 April 2013 11:10, Dan Berindei dan.berin...@gmail.com wrote: On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero sa...@infinispan.org wrote: On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Right, we should be able to tell whether that's worth doing with a pure read test with a CHMV8 and a HashMap :) IFF you find out CHMV8 is as good as HashMap for read only, you have two options: - ask the JDK team to drop the HashMap code as it's no longer needed - fix your benchmark :-P In other words, I'd consider it highly surprising and suspicious (still interesting though!) It's not as surprising as you think. On x86, volatile reads are the same as regular reads (not counting some possible reordering magic). So if a CHM read is a hash, an array access, and a list traversal, and so is HM (and I believe this is true though I'd have to review the code again to be sure), I'd expect very similar execution performance on read. I think some of the anti-collision features in V8 might come into play under some circumstances though which might affect performance in a negative way (wrt the constant big-O component) but overall in a positive way (by turning the linear big-O component into a logarithmic one). Thanks David. I know about the cost of a volatile read, what I'm referring to is that I would expect the non-concurrent Maps to generally contain some simpler code than a conccurrent one. If this was not the case, why would any JDK team maintain two different implementations? That's why I would consider it surprising if it turned out that the CHMV8 was superior over a regular one on all fronts: there certainly is some scenario in which the regular one would be a more appropriate choice, which directly proofs that blindly replacing all usages in a large project is not optimal. Of course, it might be close to optimal.. You are right, it is not superior on all fronts. It is definitely similar in terms of read, but writes will have a substantially higher cost, involving (at the very least) multiple volatile writes which are orders of magnitude more expensive than normal writes (on Intel they have the costly impact of memory fence instructions). So I don't think anyone will want to drop HashMap any time soon. :-) -- - DML ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
We also have been toying with the idea to hash each key only once, instead of both with the consistent hash (to assign the node owner) and once in the CHM backing the datacontainer. I doubt we need the datacontainer to implement Map at all, but at least if we go this way we don't want the hash to be affected by the VM instance or different nodes won't agree on the expected owner ;-) Also there where reports of it having a very bad impact on performance, I'm not sure if they where resolved yet, or are going to be resolved at all as it was important for security reasons. On 22 April 2013 12:19, Dan Berindei dan.berin...@gmail.com wrote: Right. If we have anywhere a map that's initialized from a single thread and then accessed only for reading from many threads, it probably makes sense to use a HashMap and wrap it in an UnmodifiableMap. But if it can be written from multiple threads as well, I think we should use a CHMV8. BTW, the HashMap implementation in OpenJDK 1.7 seems to have some anti-collision features (a VM-dependent hash code generator for Strings), but our version of CHMV8 doesn't. Perhaps we need to upgrade to the latest CHMV8 version? On Fri, Apr 19, 2013 at 4:32 PM, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 08:22 AM, Sanne Grinovero wrote: On 19 April 2013 13:52, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 05:17 AM, Sanne Grinovero wrote: On 19 April 2013 11:10, Dan Berindei dan.berin...@gmail.com wrote: On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero sa...@infinispan.org wrote: On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Right, we should be able to tell whether that's worth doing with a pure read test with a CHMV8 and a HashMap :) IFF you find out CHMV8 is as good as HashMap for read only, you have two options: - ask the JDK team to drop the HashMap code as it's no longer needed - fix your benchmark :-P In other words, I'd consider it highly surprising and suspicious (still interesting though!) It's not as surprising as you think. On x86, volatile reads are the same as regular reads (not counting some possible reordering magic). So if a CHM read is a hash, an array access, and a list traversal, and so is HM (and I believe this is true though I'd have to review the code again to be sure), I'd expect very similar execution performance on read. I think some of the anti-collision features in V8 might come into play under some circumstances though which might affect performance in a negative way (wrt the constant big-O component) but overall in a positive way (by turning the linear big-O component into a logarithmic one). Thanks David. I know about the cost of a volatile read, what I'm referring to is that I would expect the non-concurrent Maps to generally contain some simpler code than a conccurrent one. If this was not the case, why would any JDK team maintain two different implementations? That's why I would consider it surprising if it turned out that the CHMV8 was superior over a regular one on all fronts: there certainly is some scenario in which the regular one would be a more appropriate choice, which directly proofs that blindly replacing all usages in a large project is not optimal. Of course, it might be close to optimal.. You are right, it is not superior on all fronts. It is definitely similar in terms of read, but writes will have a substantially
Re: [infinispan-dev] CHM or CHMv8?
On 22 Apr 2013, at 08:19, Dan Berindei dan.berin...@gmail.com wrote: Right. If we have anywhere a map that's initialized from a single thread and then accessed only for reading from many threads, it probably makes sense to use a HashMap and wrap it in an UnmodifiableMap. But if it can be written from multiple threads as well, I think we should use a CHMV8. BTW, the HashMap implementation in OpenJDK 1.7 seems to have some anti-collision features (a VM-dependent hash code generator for Strings), but our version of CHMV8 doesn't. Perhaps we need to upgrade to the latest CHMV8 version? Possibly. On Fri, Apr 19, 2013 at 4:32 PM, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 08:22 AM, Sanne Grinovero wrote: On 19 April 2013 13:52, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 05:17 AM, Sanne Grinovero wrote: On 19 April 2013 11:10, Dan Berindei dan.berin...@gmail.com wrote: On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero sa...@infinispan.org wrote: On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Right, we should be able to tell whether that's worth doing with a pure read test with a CHMV8 and a HashMap :) IFF you find out CHMV8 is as good as HashMap for read only, you have two options: - ask the JDK team to drop the HashMap code as it's no longer needed - fix your benchmark :-P In other words, I'd consider it highly surprising and suspicious (still interesting though!) It's not as surprising as you think. On x86, volatile reads are the same as regular reads (not counting some possible reordering magic). So if a CHM read is a hash, an array access, and a list traversal, and so is HM (and I believe this is true though I'd have to review the code again to be sure), I'd expect very similar execution performance on read. I think some of the anti-collision features in V8 might come into play under some circumstances though which might affect performance in a negative way (wrt the constant big-O component) but overall in a positive way (by turning the linear big-O component into a logarithmic one). Thanks David. I know about the cost of a volatile read, what I'm referring to is that I would expect the non-concurrent Maps to generally contain some simpler code than a conccurrent one. If this was not the case, why would any JDK team maintain two different implementations? That's why I would consider it surprising if it turned out that the CHMV8 was superior over a regular one on all fronts: there certainly is some scenario in which the regular one would be a more appropriate choice, which directly proofs that blindly replacing all usages in a large project is not optimal. Of course, it might be close to optimal.. You are right, it is not superior on all fronts. It is definitely similar in terms of read, but writes will have a substantially higher cost, involving (at the very least) multiple volatile writes which are orders of magnitude more expensive than normal writes (on Intel they have the costly impact of memory fence instructions). So I don't think anyone will want to drop HashMap any time soon. :-) -- - DML ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org
Re: [infinispan-dev] CHM or CHMv8?
On 22 Apr 2013, at 13:37, Sanne Grinovero wrote: We also have been toying with the idea to hash each key only once, instead of both with the consistent hash (to assign the node owner) and once in the CHM backing the datacontainer. these two computations would occur on two different nodes though: once where the request originated and remotely on the node where the key is kept. So it would only make sense for local and replicated caches, which is not the critical path. I doubt we need the datacontainer to implement Map at all, The DataContainer doesn't implement Map ATM. but at least if we go this way we don't want the hash to be affected by the VM instance or different nodes won't agree on the expected owner ;-) Also there where reports of it having a very bad impact on performance, I'm not sure if they where resolved yet, or are going to be resolved at all as it was important for security reasons. On 22 April 2013 12:19, Dan Berindei dan.berin...@gmail.com wrote: Right. If we have anywhere a map that's initialized from a single thread and then accessed only for reading from many threads, it probably makes sense to use a HashMap and wrap it in an UnmodifiableMap. But if it can be written from multiple threads as well, I think we should use a CHMV8. BTW, the HashMap implementation in OpenJDK 1.7 seems to have some anti-collision features (a VM-dependent hash code generator for Strings), but our version of CHMV8 doesn't. Perhaps we need to upgrade to the latest CHMV8 version? On Fri, Apr 19, 2013 at 4:32 PM, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 08:22 AM, Sanne Grinovero wrote: On 19 April 2013 13:52, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 05:17 AM, Sanne Grinovero wrote: On 19 April 2013 11:10, Dan Berindei dan.berin...@gmail.com wrote: On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero sa...@infinispan.org wrote: On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Right, we should be able to tell whether that's worth doing with a pure read test with a CHMV8 and a HashMap :) IFF you find out CHMV8 is as good as HashMap for read only, you have two options: - ask the JDK team to drop the HashMap code as it's no longer needed - fix your benchmark :-P In other words, I'd consider it highly surprising and suspicious (still interesting though!) It's not as surprising as you think. On x86, volatile reads are the same as regular reads (not counting some possible reordering magic). So if a CHM read is a hash, an array access, and a list traversal, and so is HM (and I believe this is true though I'd have to review the code again to be sure), I'd expect very similar execution performance on read. I think some of the anti-collision features in V8 might come into play under some circumstances though which might affect performance in a negative way (wrt the constant big-O component) but overall in a positive way (by turning the linear big-O component into a logarithmic one). Thanks David. I know about the cost of a volatile read, what I'm referring to is that I would expect the non-concurrent Maps to generally contain some simpler code than a conccurrent one. If this was not the case, why would any JDK team maintain two different implementations? That's why I would consider it surprising if it turned out that the CHMV8 was superior over a regular one on all fronts: there certainly is some scenario in which the regular one would be a more appropriate
Re: [infinispan-dev] CHM or CHMv8?
Do you have the numbers for JDK 7 as well? Radim - Original Message - | From: Manik Surtani msurt...@redhat.com | To: infinispan -Dev List infinispan-dev@lists.jboss.org | Sent: Friday, April 19, 2013 4:35:53 AM | Subject: [infinispan-dev] CHM or CHMv8? | | Guys, | | Based on some recent micro benchmarks I've been doing, I've seen: | | MapStressTest configuration: capacity 10, test running time 60 seconds | Testing mixed read/write performance with capacity 100,000, keys 300,000, | concurrency level 32, threads 12, read:write ratio 0:1 | Container CHM Ops/s 21,165,771.67 Gets/s 0.00 Puts/s | 21,165,771.67 HitRatio 100.00 Size262,682 stdDev 77,540.73 | Container CHMV8 Ops/s 33,513,807.09 Gets/s 0.00 Puts/s | 33,513,807.09 HitRatio 100.00 Size262,682 stdDev 77,540.73 | | So under high concurrency (12 threads, on my workstation with 12 hardware | threads - so all threads are always working), we see that Infinispan's CHMv8 | implementation is 50% faster than JDK6's CHM implementation when doing puts. | | We use a fair number of CHMs all over Infinispan's codebase. By default, | these are all JDK-provided CHMs. But we have the option to switch to our | CHMv8 implementation by passing in -Dinfinispan.unsafe.allow_jdk8_chm=true. | | The question is, should this be the default? Thoughts, opinions? | | - M | | -- | Manik Surtani | ma...@jboss.org | twitter.com/maniksurtani | | Platform Architect, JBoss Data Grid | http://red.ht/data-grid | | | ___ | infinispan-dev mailing list | infinispan-dev@lists.jboss.org | https://lists.jboss.org/mailman/listinfo/infinispan-dev | ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
+1 to make CHMv8 the default on JDK6 and JDK7 But I'm not convinced we should make it the default for JDK8 - even though we don't know exactly what we're getting with the JDK's implementation. On Fri, Apr 19, 2013 at 5:39 AM, David M. Lloyd david.ll...@redhat.comwrote: On 04/18/2013 09:35 PM, Manik Surtani wrote: Guys, Based on some recent micro benchmarks I've been doing, I've seen: MapStressTest configuration: capacity 10, test running time 60 seconds Testing mixed read/write performance with capacity 100,000, keys 300,000, concurrency level 32, threads 12, read:write ratio 0:1 Container CHM Ops/s 21,165,771.67 Gets/s 0.00 Puts/s 21,165,771.67 HitRatio 100.00 Size262,682 stdDev 77,540.73 Container CHMV8 Ops/s 33,513,807.09 Gets/s 0.00 Puts/s 33,513,807.09 HitRatio 100.00 Size262,682 stdDev 77,540.73 So under high concurrency (12 threads, on my workstation with 12 hardware threads - so all threads are always working), we see that Infinispan's CHMv8 implementation is 50% faster than JDK6's CHM implementation when doing puts. We use a fair number of CHMs all over Infinispan's codebase. By default, these are all JDK-provided CHMs. But we have the option to switch to our CHMv8 implementation by passing in -Dinfinispan.unsafe.allow_jdk8_chm=true. The question is, should this be the default? Thoughts, opinions? The JDK's concurrency code - especially CHM - changes all the time. You'd be very well-served, in my opinion, to go with something like CHMv8 just because you could be so much more sure that you'll have more consistent (and possibly better, but definitely more consistent) performance across all JVMs, instead of being at the mercy of whatever particular implementation happens to run on whatever JVM. -- - DML ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
Why not. Only doubt I'd have is that other usages of the CHM are - I guess - services registry and similar configuration tools, for which write performance is irrelevant: your test measured puts, are there drawbacks on gets or memory usage? Recently you changed all (most?) CHM creations to use a consistent factory, maybe we could improve on that by actually using a couple of factories which differentiate on the intended usage of the CHM: for example some maps who change very infrequently - mostly during boot or reconfiguration, maybe even topology change - could be better served by a non concurrent structure using copy-on-wrtite. Sanne On 19 Apr 2013 08:48, Dan Berindei dan.berin...@gmail.com wrote: +1 to make CHMv8 the default on JDK6 and JDK7 But I'm not convinced we should make it the default for JDK8 - even though we don't know exactly what we're getting with the JDK's implementation. On Fri, Apr 19, 2013 at 5:39 AM, David M. Lloyd david.ll...@redhat.comwrote: On 04/18/2013 09:35 PM, Manik Surtani wrote: Guys, Based on some recent micro benchmarks I've been doing, I've seen: MapStressTest configuration: capacity 10, test running time 60 seconds Testing mixed read/write performance with capacity 100,000, keys 300,000, concurrency level 32, threads 12, read:write ratio 0:1 Container CHM Ops/s 21,165,771.67 Gets/s 0.00 Puts/s 21,165,771.67 HitRatio 100.00 Size262,682 stdDev 77,540.73 Container CHMV8 Ops/s 33,513,807.09 Gets/s 0.00 Puts/s 33,513,807.09 HitRatio 100.00 Size262,682 stdDev 77,540.73 So under high concurrency (12 threads, on my workstation with 12 hardware threads - so all threads are always working), we see that Infinispan's CHMv8 implementation is 50% faster than JDK6's CHM implementation when doing puts. We use a fair number of CHMs all over Infinispan's codebase. By default, these are all JDK-provided CHMs. But we have the option to switch to our CHMv8 implementation by passing in -Dinfinispan.unsafe.allow_jdk8_chm=true. The question is, should this be the default? Thoughts, opinions? The JDK's concurrency code - especially CHM - changes all the time. You'd be very well-served, in my opinion, to go with something like CHMv8 just because you could be so much more sure that you'll have more consistent (and possibly better, but definitely more consistent) performance across all JVMs, instead of being at the mercy of whatever particular implementation happens to run on whatever JVM. -- - DML ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. On Fri, Apr 19, 2013 at 11:07 AM, Sanne Grinovero sa...@infinispan.orgwrote: Why not. Only doubt I'd have is that other usages of the CHM are - I guess - services registry and similar configuration tools, for which write performance is irrelevant: your test measured puts, are there drawbacks on gets or memory usage? Recently you changed all (most?) CHM creations to use a consistent factory, maybe we could improve on that by actually using a couple of factories which differentiate on the intended usage of the CHM: for example some maps who change very infrequently - mostly during boot or reconfiguration, maybe even topology change - could be better served by a non concurrent structure using copy-on-wrtite. Sanne On 19 Apr 2013 08:48, Dan Berindei dan.berin...@gmail.com wrote: +1 to make CHMv8 the default on JDK6 and JDK7 But I'm not convinced we should make it the default for JDK8 - even though we don't know exactly what we're getting with the JDK's implementation. On Fri, Apr 19, 2013 at 5:39 AM, David M. Lloyd david.ll...@redhat.comwrote: On 04/18/2013 09:35 PM, Manik Surtani wrote: Guys, Based on some recent micro benchmarks I've been doing, I've seen: MapStressTest configuration: capacity 10, test running time 60 seconds Testing mixed read/write performance with capacity 100,000, keys 300,000, concurrency level 32, threads 12, read:write ratio 0:1 Container CHM Ops/s 21,165,771.67 Gets/s 0.00 Puts/s 21,165,771.67 HitRatio 100.00 Size262,682 stdDev 77,540.73 Container CHMV8 Ops/s 33,513,807.09 Gets/s 0.00 Puts/s 33,513,807.09 HitRatio 100.00 Size262,682 stdDev 77,540.73 So under high concurrency (12 threads, on my workstation with 12 hardware threads - so all threads are always working), we see that Infinispan's CHMv8 implementation is 50% faster than JDK6's CHM implementation when doing puts. We use a fair number of CHMs all over Infinispan's codebase. By default, these are all JDK-provided CHMs. But we have the option to switch to our CHMv8 implementation by passing in -Dinfinispan.unsafe.allow_jdk8_chm=true. The question is, should this be the default? Thoughts, opinions? The JDK's concurrency code - especially CHM - changes all the time. You'd be very well-served, in my opinion, to go with something like CHMv8 just because you could be so much more sure that you'll have more consistent (and possibly better, but definitely more consistent) performance across all JVMs, instead of being at the mercy of whatever particular implementation happens to run on whatever JVM. -- - DML ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Sanne On Fri, Apr 19, 2013 at 11:07 AM, Sanne Grinovero sa...@infinispan.org wrote: Why not. Only doubt I'd have is that other usages of the CHM are - I guess - services registry and similar configuration tools, for which write performance is irrelevant: your test measured puts, are there drawbacks on gets or memory usage? Recently you changed all (most?) CHM creations to use a consistent factory, maybe we could improve on that by actually using a couple of factories which differentiate on the intended usage of the CHM: for example some maps who change very infrequently - mostly during boot or reconfiguration, maybe even topology change - could be better served by a non concurrent structure using copy-on-wrtite. Sanne On 19 Apr 2013 08:48, Dan Berindei dan.berin...@gmail.com wrote: +1 to make CHMv8 the default on JDK6 and JDK7 But I'm not convinced we should make it the default for JDK8 - even though we don't know exactly what we're getting with the JDK's implementation. On Fri, Apr 19, 2013 at 5:39 AM, David M. Lloyd david.ll...@redhat.com wrote: On 04/18/2013 09:35 PM, Manik Surtani wrote: Guys, Based on some recent micro benchmarks I've been doing, I've seen: MapStressTest configuration: capacity 10, test running time 60 seconds Testing mixed read/write performance with capacity 100,000, keys 300,000, concurrency level 32, threads 12, read:write ratio 0:1 Container CHM Ops/s 21,165,771.67 Gets/s 0.00 Puts/s 21,165,771.67 HitRatio 100.00 Size262,682 stdDev 77,540.73 Container CHMV8 Ops/s 33,513,807.09 Gets/s 0.00 Puts/s 33,513,807.09 HitRatio 100.00 Size262,682 stdDev 77,540.73 So under high concurrency (12 threads, on my workstation with 12 hardware threads - so all threads are always working), we see that Infinispan's CHMv8 implementation is 50% faster than JDK6's CHM implementation when doing puts. We use a fair number of CHMs all over Infinispan's codebase. By default, these are all JDK-provided CHMs. But we have the option to switch to our CHMv8 implementation by passing in -Dinfinispan.unsafe.allow_jdk8_chm=true. The question is, should this be the default? Thoughts, opinions? The JDK's concurrency code - especially CHM - changes all the time. You'd be very well-served, in my opinion, to go with something like CHMv8 just because you could be so much more sure that you'll have more consistent (and possibly better, but definitely more consistent) performance across all JVMs, instead of being at the mercy of whatever particular implementation happens to run on whatever JVM. -- - DML ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org
Re: [infinispan-dev] CHM or CHMv8?
On 19 April 2013 11:10, Dan Berindei dan.berin...@gmail.com wrote: On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero sa...@infinispan.org wrote: On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Right, we should be able to tell whether that's worth doing with a pure read test with a CHMV8 and a HashMap :) IFF you find out CHMV8 is as good as HashMap for read only, you have two options: - ask the JDK team to drop the HashMap code as it's no longer needed - fix your benchmark :-P In other words, I'd consider it highly surprising and suspicious (still interesting though!) Cheers, Sanne ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
Ok, I've created https://issues.jboss.org/browse/ISPN-3022 In fact, we should also re-implement the BoundedConcurrentHashMap - the basis for LIRS and LRU eviction algorithms - to use techniques similar to CHMv8 rather than the old segment-based approach. https://issues.jboss.org/browse/ISPN-3023 Anyone has a few spare cycles - and is really good with complex concurrency code - want to take this on? ;) - M On 19 Apr 2013, at 09:06, Manik Surtani msurt...@redhat.com wrote: On 19 Apr 2013, at 05:07, Sanne Grinovero sa...@infinispan.org wrote: Why not. Only doubt I'd have is that other usages of the CHM are - I guess - services registry and similar configuration tools, for which write performance is irrelevant: your test measured puts, are there drawbacks on gets or memory usage? See the original announcement on concurrency-interest by Doug Lea, and the subsequent comments. The design is up here too. One of the goals was to drastically reduce memory usage with CHMv8. http://comments.gmane.org/gmane.comp.java.jsr.166-concurrency/8140 Interestingly, Netty uses a backported CHMv8 as well - apparently inspired by our inclusion of it in Infinispan. ;) https://github.com/netty/netty/issues/1052 -M -- Manik Surtani ma...@jboss.org twitter.com/maniksurtani Platform Architect, JBoss Data Grid http://red.ht/data-grid -- Manik Surtani ma...@jboss.org twitter.com/maniksurtani Platform Architect, JBoss Data Grid http://red.ht/data-grid ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
On 19 Apr 2013, at 08:47, Dan Berindei wrote: +1 to make CHMv8 the default on JDK6 and JDK7 +1 Cheers, -- Mircea Markus Infinispan lead (www.infinispan.org) ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
On 19 Apr 2013, at 13:16, Manik Surtani wrote: https://issues.jboss.org/browse/ISPN-3022 In fact, we should also re-implement the BoundedConcurrentHashMap - the basis for LIRS and LRU eviction algorithms - to use techniques similar to CHMv8 rather than the old segment-based approach. https://issues.jboss.org/browse/ISPN-3023 Anyone has a few spare cycles - and is really good with complex concurrency code - want to take this on? ;) Whilst this is nice to have, I don't think this should be tackled now, unless some contributor is willing to look at it. We have quite some bugs that need fixing first, then performance :) Cheers, -- Mircea Markus Infinispan lead (www.infinispan.org) ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
On 04/19/2013 05:17 AM, Sanne Grinovero wrote: On 19 April 2013 11:10, Dan Berindei dan.berin...@gmail.com wrote: On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero sa...@infinispan.org wrote: On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Right, we should be able to tell whether that's worth doing with a pure read test with a CHMV8 and a HashMap :) IFF you find out CHMV8 is as good as HashMap for read only, you have two options: - ask the JDK team to drop the HashMap code as it's no longer needed - fix your benchmark :-P In other words, I'd consider it highly surprising and suspicious (still interesting though!) It's not as surprising as you think. On x86, volatile reads are the same as regular reads (not counting some possible reordering magic). So if a CHM read is a hash, an array access, and a list traversal, and so is HM (and I believe this is true though I'd have to review the code again to be sure), I'd expect very similar execution performance on read. I think some of the anti-collision features in V8 might come into play under some circumstances though which might affect performance in a negative way (wrt the constant big-O component) but overall in a positive way (by turning the linear big-O component into a logarithmic one). -- - DML ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
On 04/19/2013 08:22 AM, Sanne Grinovero wrote: On 19 April 2013 13:52, David M. Lloyd david.ll...@redhat.com wrote: On 04/19/2013 05:17 AM, Sanne Grinovero wrote: On 19 April 2013 11:10, Dan Berindei dan.berin...@gmail.com wrote: On Fri, Apr 19, 2013 at 12:58 PM, Sanne Grinovero sa...@infinispan.org wrote: On 19 April 2013 10:37, Dan Berindei dan.berin...@gmail.com wrote: Testing mixed read/write performance with capacity 10, keys 30, concurrency level 32, threads 12, read:write ratio 99:1 Container CHM Ops/s 5178894.77 Gets/s 5127105.82 Puts/s 51788.95 HitRatio 86.23 Size 177848 stdDev 60896.42 Container CHMV8 Ops/s 5768824.37 Gets/s 5711136.13 Puts/s 57688.24 HitRatio 84.72 Size 171964 stdDev 60249.99 Nice, thanks. The test is probably limited by the 1% writes, but I think it does show that reads in CHMV8 are not slower than reads in OpenJDK7's CHM. I haven't measured it, but the memory footprint should also be better, because it doesn't use segments any more. AFAIK the memoryCHMV8 also uses copy-on-write at the bucket level, but we could definitely do a pure read test with a HashMap to see how big the performance difference is. By copy-on-write I didn't mean on the single elements, but on the whole map instance: private volatile HashMap configuration; synchronized addConfigurationProperty(String, String) { HashMap newcopy = new HashMap( configuration ): newcopy.put(..); configuration = newcopy; } Of course that is never going to scale for writes, but if writes stop at runtime after all services are started I would expect that the simplicity of the non-threadsafe HashMap should have some benefit over CHM{whatever}, or it would have been removed already? Right, we should be able to tell whether that's worth doing with a pure read test with a CHMV8 and a HashMap :) IFF you find out CHMV8 is as good as HashMap for read only, you have two options: - ask the JDK team to drop the HashMap code as it's no longer needed - fix your benchmark :-P In other words, I'd consider it highly surprising and suspicious (still interesting though!) It's not as surprising as you think. On x86, volatile reads are the same as regular reads (not counting some possible reordering magic). So if a CHM read is a hash, an array access, and a list traversal, and so is HM (and I believe this is true though I'd have to review the code again to be sure), I'd expect very similar execution performance on read. I think some of the anti-collision features in V8 might come into play under some circumstances though which might affect performance in a negative way (wrt the constant big-O component) but overall in a positive way (by turning the linear big-O component into a logarithmic one). Thanks David. I know about the cost of a volatile read, what I'm referring to is that I would expect the non-concurrent Maps to generally contain some simpler code than a conccurrent one. If this was not the case, why would any JDK team maintain two different implementations? That's why I would consider it surprising if it turned out that the CHMV8 was superior over a regular one on all fronts: there certainly is some scenario in which the regular one would be a more appropriate choice, which directly proofs that blindly replacing all usages in a large project is not optimal. Of course, it might be close to optimal.. You are right, it is not superior on all fronts. It is definitely similar in terms of read, but writes will have a substantially higher cost, involving (at the very least) multiple volatile writes which are orders of magnitude more expensive than normal writes (on Intel they have the costly impact of memory fence instructions). So I don't think anyone will want to drop HashMap any time soon. :-) -- - DML ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev
Re: [infinispan-dev] CHM or CHMv8?
On 04/18/2013 09:35 PM, Manik Surtani wrote: Guys, Based on some recent micro benchmarks I've been doing, I've seen: MapStressTest configuration: capacity 10, test running time 60 seconds Testing mixed read/write performance with capacity 100,000, keys 300,000, concurrency level 32, threads 12, read:write ratio 0:1 Container CHM Ops/s 21,165,771.67 Gets/s 0.00 Puts/s 21,165,771.67 HitRatio 100.00 Size262,682 stdDev 77,540.73 Container CHMV8 Ops/s 33,513,807.09 Gets/s 0.00 Puts/s 33,513,807.09 HitRatio 100.00 Size262,682 stdDev 77,540.73 So under high concurrency (12 threads, on my workstation with 12 hardware threads - so all threads are always working), we see that Infinispan's CHMv8 implementation is 50% faster than JDK6's CHM implementation when doing puts. We use a fair number of CHMs all over Infinispan's codebase. By default, these are all JDK-provided CHMs. But we have the option to switch to our CHMv8 implementation by passing in -Dinfinispan.unsafe.allow_jdk8_chm=true. The question is, should this be the default? Thoughts, opinions? The JDK's concurrency code - especially CHM - changes all the time. You'd be very well-served, in my opinion, to go with something like CHMv8 just because you could be so much more sure that you'll have more consistent (and possibly better, but definitely more consistent) performance across all JVMs, instead of being at the mercy of whatever particular implementation happens to run on whatever JVM. -- - DML ___ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev