Charles Oliver Nutter schrieb: > On Monday, November 2, 2009, Jochen Theodorou <[email protected]> wrote: >> my numbers show, that on integer based benchmarks Groovy could be around >> 30% slower than Java. The GSOC project which realizes a bytecode level >> optimizing compiler for Groovy shows this is very possible. The only >> reasons we don't go with that solution is that it requires Groovy to >> start two runtimes and as a library we cannot do that. So it would be >> only an option if Groovy is run from the command line. And for for >> example Grails this does not really look like an option. > > That is unfortunate. Because JRuby has an interpreted mode, adding the > profile driven optimizations will not be at all difficult for us. > Shouldn't you be able to modify your compiler to gather profile data? > I am also planning to do that for JRuby since many users want to be > able to ship only .class files. > > Or perhaps someone could wirte a Groovy interpreter? JRuby's > interpreter obviously does not perform as well as the compiled code, > but it still manages to be faster than the C versions of Ruby and > nearly as fast as Groovy, plus we can gather profile data to make the > eventual compiled result much faster.
Such an interpreter would still need a static class construct, so the interpreter would interpret only the contents of the method. That means the method would first create some kind of tree and evaluate that, with optionally storing the tree. This imposes of course a big startup cost. Without having such a tree it is not easy to tell if an interpreter could have any advantage at runtime. But frankly I thought about this too. I thought that maybe it would be good to replace the method contents and such an interpreter could be of help here. This is kind of like the bytecode based version, only that we don't need an agent. The additional data structure looks quite surplus to me but if the VM does not offer more... Of course replacing the contents of the method means invalidation of the method to some extend and here the question is how to handle multiple threads. And in the multiple threads are the point that worry me. Because in the current way I think I found a solution that works without using any explicit volatiles. If the method is replaced, then I don't see how that should work without a volatile. And then it would be a volatile per method call again. Something I identify as root of evil in Groovy atm. In Groovy we don't have a runtime per thread, so I don't think that works for us. With invokedynamic there would be the solution, that we make a dynamic method call to the contents of the method, with the interpreter being the default. I we replace the interpreter, then we can invalidate the callsite. So with invokedynamic this may make sense, without it does not really. >> one volatile is enough to cause problems to hotspot. I found that in >> Java 1.7 for example boxing is much less of a problem. If hotspot finds >> the path primitive, boxed, unboxed, then it removes those two surplus >> operations. So boxing by itself would not be a problem. But is you >> access the volatile before unboxing, then this path no longer works and >> hotspot won't remove the surplus boxing. > > Yes, I do realize this, and discussions with John Rose often led us to > the conclusion that JRuby's next perf boost may come from eliminating > those volatile checks. But it is very hard to eliminate them when we > can't safely "push" updates out to call sites (see my earlier email on > "active" call site invalidation). Perhaps I will take another look and > see if I can find a way. wellI think I found a way for Groovy that eliminates all volatile usages, but that depends on how multi threading is done in Groovy/Java and on the java memory model. >> Artificial stack-trace >> maintenance is something we don't do, so there is no problem for us. > > Yes, thankfully we have managed to get stack maintenance pretty fast, > fast enough that we are as fast or faster than groovy on most > microbenchmarks. But we are hoping to allow users to turn it off very > soon, which can double or triple the performance of method > invocations. A simple fib(30) goes from 0.17s to 0.9s inthat mode. > Hopefully it will be stable soon...and maybe even default. may I ask what you even need it for? >> why is it megamorphic for you guys? > > It is megamorphic for everyone. Each and times and their Ilk are all > ping-ponging through a method that receives a closure. Since there are > many callers of these methods, the closure passed varies widely and > the eventual invocation of that closure is polymorphic. On Hotspot, at > least, this prevents the closure from being unlined all the way back > to the caller of 'each' and so you don't get the full set of > optimizations. You mean for example the "each" method I guess, not the method calling each. Well you could imagine that the method calling each first inlines the each method and then the closure. Hotspot would make many lifes more easy if that would be done. [...] > Have you done much exploration into how well Groovy code is inlining > in the JVM? My explorations with JRuby have shown me that with certain > JRuby flags turned on, I can get everything to inline, even across > dynamic calls, even into user-created code. My next goal is to > eliminate anything that interferes with inlined optimizations. Fun > times ahead reading assembly output :) your hotspot does inline across volatiles? bye blackdrag -- Jochen "blackdrag" Theodorou The Groovy Project Tech Lead (http://groovy.codehaus.org) http://blackdragsview.blogspot.com/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "JVM Languages" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/jvm-languages?hl=en -~----------~----~----~----~------~----~------~--~---
