Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala

Luca Bruno wrote:
Threads are very heavy compared to an optimised implementation of
'goroutines' or whatever.  Certainly you can emulate them but it's not
going to be an efficient way of implementing algorithms unless someone
puts in the work to make it efficient under the hood.

If convenience matters more than efficiency, then no problem.

Do you have any benchmark? I wouldn't say that loudly in general.

No, I don't have a benchmark, but a Thread is actually a kernel
process on Linux, whereas a goroutine could be just an allocated
mini-stack of 100 bytes (assuming enough static analysis to figure out
required stack depth) and some housekeeping structures.  Switching
between threads means waiting for the Linux kernel to schedule it.
Switching to/from a go/coroutine could be a longjmp (having read some
of the Pth implementation stuff).

To me it seems that they would not be comparable in efficiency.

I think that the idea of goroutines is that they can be used
everywhere in the code, just like an 'if' or a 'for'.  So there could
be 100s of them active.  If they only need 100-200 bytes each, that is
manageable.  If they require an entire kernel process for each one,
then it does not seem like a good approach.

I guess if we're just talking about one or two extra threads running
at the top level of the application, then I agree, that is fine.  But
using them as a fundamental control-flow structure within the language
needs a more optimised implementation.

In this case we're talking about an Iterator.  A traditional
non-coroutine implementation of an Iterator would hold state in the
Iterator object and generate new objects to return one by one on
demand, implemented with an internal generate_next() call or similar.
This will run in a single thread.  A co-routine or generator type
implementation turns the code inside out, and holds state on its own
private stack (i.e. local variables) instead of inside the Iterator
object.  If implemented as a coroutine the iteration will also run
inside a single thread, and the equivalent of the generate_next() call
is a longjmp switch to the coroutine and a longjmp back.  This is
comparable to the non-coroutine implementation.  However, if the
coroutine is running in a separate thread, then we require the kernel
to schedule a context switch.  This HAS to be slower -- at least
that's how it seems to me.

Maybe this could be made more workable using 'Pth' instead of kernel
threads, or by using the async stuff already in Vala.  (Sorry, I'm not
up to speed on that yet.)


 Jim Peters                  (_)/=\~/_(_)                 jim uazu net
                          (_)  /=\  ~/_  (_)
 UazĂș                  (_)    /=\    ~/_    (_)                http://
 in Peru            (_) ____ /=\ ____ ~/_ ____ (_)  

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]