On Jan 3, 2004, at 5:24 PM, Matt Fowles wrote:

All~

I have a naive question:

Why must each thread have its own interpreter?

The short answer is that the bulk of the state of the virtual machine (including, and most importantly, its registers and register stacks) needs to be per-thread, since it represents the "execution context" which is logically thread-local. Stuff like the globals stash may or may not be shared (depending on the thread semantics we want), but as I understand it the "potentially shared" stuff is actually only a small part of the bits making up the VM.


That said, I do think we have a terminology problem, since I initially had the same question you did, and I think my confusion mostly stems from there being no clear terminology to distinguish between 2 "interpreters" which are completely independent, and 2 "interpreters" which represent 2 threads of the same program. In the latter case, those 2 "interpreters" are both part of one "something", and we don't have a name for that "something". It would be clearer to say that we have two "threads" in one "interpreter", and just note that almost all of our state lives in the "thread" structure. (That would mean that the thing which is being passed into all of our API would be called the thread, not the interpreter, since it's a thread which represents an execution context.) It's just (or mostly) terminology, but it's causing confusion.

Why not have the threads that share everything share interpreters. We can have these threads be within the a single interpreter thus eliminating the need for complicated GC locking and resource sharing complexity. Because all of these threads will be one kernel level thread, they will not actually run concurrently and there will be no need to lock them. We will have to implement a rudimentary scheduler in the interpreter, but I don't think that is actually that hard.

There are 2 main problems with trying to emulate threads this way:


1) It would likely kill the performance gains of JIT.

2) Calls into native libraries could block the entire VM. (We can't manually timeslice external native code.) Even things such as regular expressions can take an unbounded amount of time, and the internals of the regex engine will be in C--so we couldn't timeslice without slowing them down.

And basically, people are going to want "real" threads--they'll want access to the full richness and power afforded by an API such as pthreads, and the "real" threading libraries (and the OS) have already done all of the really hard work.

This allows threads to have completely shared state, at the cost of not being quite as efficient on SMP (they might be more efficient on single processors as there are fewer kernel traps necessary).

Not likely to be more efficient even on a single processor, since even if a process is single threaded it is being preempted by other processes. (On Mac OS X, I've not been able to create a case where being multithreaded is a slowdown in the absence of locking--even for pure computation on a single processor machine, being multithreaded is actually a slight performance gain.)


Programs that want to run faster on an SMP will use threads without shared that use events to communicate.

It's nice to have speed gains on MP machines without having to redesign your application, especially as MP machines are quickly becoming the norm.


(which probably provides better performance, as there will be fewer faults to main memory because of cache misses and shared data).

Probably not faster actually, since you'll end up with more data copying (and more total data).


I understand if this suggestion is dismissed for violating the rules, but I would like an answer to the question simply because I do not know the answer.

I hope my answers are useful. I think it's always okay to ask questions.


JEff

Reply via email to