[concurrency-interest] Fast control transfer from one thread to another?
Charles Oliver Nutter
headius at headius.com
Mon Aug 8 16:24:06 EDT 2011
On Mon, Aug 8, 2011 at 3:30 PM, Ron Pressler <ron.pressler at gmail.com> wrote:
> If each fiber is represented by a thread, then any transfer of control
> between fibers would require an OS task switch, which is bound to be slower
> than C Ruby's lightweight threads. However, the erjang project has
> implemented erlang on top of the JVM, and erlang requires lots of "fiber"
> switches for its actors. The way they did it is by using a modified version
> of Kilim , which uses bytecode instrumentation to implement continuations
> with stack-capture - the same way C Ruby does it, I presume.
This would work, but the execution performance of bytecode
instrumentation would almost certainly be worse than what we have now.
Kilim-style bytecode manipulation also only works if you can
instrument all the code you're passing through (leaves excluded),
which would mean almost all of JRuby would need to be instrumented in
I would also wager there's no change of inlining code that's been
instrumented...or at least a large class of optimizations would not
work in the presence of stack trampolines.
> Scala uses java's Fork/Join tasks for its actor scheduling, and it sounds
> like you might be able to use that too. You transfer control to another
> fiber with fork, and block yourself with join.
I'm essentially doing this now with park/unpark, but I'll look into
whether Fork/Join makes it cleaner.
> But in any case, for best performance you will probably have to abandon the
> one-thread-per-fiber model (which is also expensive on memory)
Yes, I'd love to :) But unfortunately there's no way to do that on the
JVM right now.
Perhaps this is a good time to lobby for concurrency-interest's
support in Lukas Stadler's JVM coroutines. He implemented them for
OpenJDK as part of his PhD work, and they provide much faster Fiber
context-switching than even the C implementations of Ruby. I believe
he's looking to launch a JSR soon...and it seems like
pausable/resumable workers (in the form of coroutines) might be a
useful feature for concurrency (especially atop blocking library calls
that would steal a thread forever). Imagine having a worker pool that
only has N threads for M > N running worker coroutines, and uses
coroutine suspend/resume to choose between them as necessary.
More information about the Concurrency-interest