On Mon, Dec 19, 2011 at 2:17 AM, Tim F. [email protected] wrote:
This is good information.
For users such as (project vert.x) we guarantee that JRuby code is always
executed by the same thread (event loop), so we don’t need it to be
threadsafe. I’m actually more interested that stuff is not made volatile,
since, aiui volatile writes cause a flush even if there are no other reads,
and hence incur a performance penalty.
Somewhat. Volatile writes on the JVM (into “volatile” fields) should
only impact the cache line where a given core is caching the given
field’s value. It’s not a full cache flush by any means. There’s
certainly a performance hit, but it’s not catastrophic.
Looking at the wiki page it seems most instance operations aren’t volatile
so I think we should be ok. I’m be more concerned if heavily used classes
such as Hash were made thread-safe.
Before writing this document up, I actually did some experiments to
make instance variables volatile: Two attempts to make instance vars volatile. The ARA version is 10-15% slower, and Unsafe version is 5-10% slower. · GitHub
They both worked and both carried with them the expected performance
hit, but that hit was not as bad as I expected (5-15% for a
variable-heavy benchmark). It’s still too high for me to force it on
all objects in JRuby, of course.
What we may do, instead, is offer a special Struct type or Ruby
superclass that guarantees its instance variables are always volatile,
perhaps by requiring the class creation explicitly state the variables
it will use. That would likely be sufficient for volatility-sensitive
thread programming.
Would it be possible to have someway of telling JRuby that it’s being run in
single threaded mode (I think Rhino does something like this), and if so,
then it didn’t use the thread-safe versions of classes?
I think you’ll find that in practice, the thread-safety mechanisms we
use won’t impact steady-state performance. The “write” perf impact is
limited to modifying class-level data like method tables, constants,
and class variables…all ideally happening only at boot time. The
“read” perf impact is mitigated by our various caching strategies,
which avoid hitting volatile structures and locks unless the cache
must be invalidated.
If you get to a point where you think you’re seeing unreasonably poor
multi-thread scaling, we can explore that further. Until then, I think
you’ll be ok with thread-safety guarantees always on.