[plt-scheme] Creating a suspended thread

From: Eli Barzilay (eli at barzilay.org)
Date: Tue Apr 14 00:01:57 EDT 2009

On Apr 13, Marc Feeley wrote:
> The problem of conflating thread creation and activation is no
> different than the problem of conflating function creation and
> variable definition (which Scheme chose not to conflate).  You can
> simulate anonymous functions with named functions by using a
> temporary name.  But you pay a price in program clarity (elegance?)
> and in run time cost (unless you have a Sufficiently Smart(tm)
> compiler).

Going down to more primitive forms doesn't always mean gaining clarity
(or elegance) -- otherwise machine code would be much better than
Scheme, and `call-with-current-continuation' would be much better than
`let/cc'.  In other words, Scheme *did* choose to conflate a good
number of features in its function form...

More seriously, if the kind of problems that are solved by separating
thread-creation from thread-activation can be solved with channels,
then I choose the higher-level operation.  If it does turn out that
there are some cases where the mzscheme facilities are insufficient,
then my guess is that these cases are rare enough that paying the
extra cost (if there is any) is perfectly fine with me -- in exactly
the same way that I still prefer `lambda' as a better alternative to
the low level features it conflates.

> The "thread/suspend" procedure submitted by Matthew runs about 5%
> slower than the "thread" procedure alone (on MzScheme v4.1 + Intel
> Mac OS X).  So the additional semaphore operations don't seem to add
> much of an overhead.  But that is because thread creation in
> MzScheme is slow in comparison to the semaphore operations (about 45
> microseconds per thread creation + termination).  In a system with
> faster thread creation operations the overhead becomes quite
> noticeable (Gambit is about 45 times faster, i.e. one microsecond
> per thread creation + termination).

I'm getting different numbers: I get thread creation and termination
at about 10 microseconds -- and that's for both versions; the
difference is in the noise.

(For these two lines:

  (time (for ([i (in-range 100000)]) (kill-thread (thread void))))
  (time (for ([i (in-range 100000)]) (kill-thread (thread/suspended void))))

I'm getting these medians out of 13 runs of each:

  first:  cpu time: 1057 real time: 1057 gc time: 123
  second: cpu time: 1035 real time: 1036 gc time: 148


          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!

Posted on the users mailing list.