gcl-devel
[Top][All Lists]
Advanced

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

[Gcl-devel] Re: Parallel GCL


From: Camm Maguire
Subject: [Gcl-devel] Re: Parallel GCL
Date: 22 Oct 2005 22:05:33 -0400
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Greetings!

Robert Boyer <address@hidden> writes:

> > Just a tidbit for those interested.
> 
> Believe it or not, I found your message on fasd too hard to understand!
> 

My apologies -- clarity and concision in communication is not one of
my strengths, alas.  I do agree that a good set of examples would be
most useful.  Perhaps you could help review and simplify the code
below toward this end.  We could even include it in our documentation
if you find it useful.  Though currently quite crude, you can see how
a parallel-let, "parallel-and" and "parallel-or" would be implemented
(I believe) from this example -- if not please let me know and I will
try to elaborate.

Of course the overhead in what we have now can be greatly reduced.  It
was designed to support network server applications and thus carries
around much more baggage than what we would need in a fork-based
parallel gcl.  Greatly steamlining the i/o, perhaps including fasd
compression, moving from sockets to simple pipes, preallocation of
memory on the stack of each child to forestall gc, and providing a
simple cleanup call to terminate the child processes is where we would
go in pursuing this idea.  Of course in addition to other
disadvantages vis a vis threads, this approach would not work (at
least not in a straightforward fashion) on windows.  Obvious
advantages are that one need not worry about any locking, race
conditions, special variables, or other resource conflicts.  

I really like Warren's suggestion of having the compiler help you out
with some automatic parallelization given sufficient analysis of the
component functions. I also tend to favor the terse, clear and simple
traditional lisp syntax (i.e. let, psetq, maybe new ones si::pand,
si::por) where the individual thread behavior is completely under the
hood as compared with low level explicit manipulations of mutexes and
explicit thread creation and destruction.  The latter is what one
would do in C, but surely one can do better than just lifting the
concepts straight into lisp -- but then again maybe this isn't a big
deal.  I always thought that if one wanted low-level control like that
one would use C to begin with.

Anyway, thoughts/feedback most welcome.

=============================================================================
(defvar *waits* (with-open-file 
                 (s "/dev/random" :element-type '(unsigned-byte 32))
                 (mapcar (lambda (x) (read-byte s)) (make-list 10))))
(defun complicated-function (x) 
  (let ((y (nth (mod (si::getpid) 10) *waits*)))
    (sleep (mod y 30))
    (cons x (mod y x))))
(defun one-result (s) 
  (format s "~s~%" (complicated-function (read s nil 10)))
  (bye))
(defun many-results (s) 
  (let ((x (read s nil 'eof)))
    (unless (eq x 'eof)
      (format s "~s~%" (complicated-function x))
      (many-results s))
    (bye)))
(defun watch (x) 
  (cond ((some 'streamp x) 
         (print x)
         (sleep 1)
         (watch (mapcar (lambda (x) (if (and (streamp x) (listen x)) (read x) 
x)) x)))
        (x)))

(setq l1 (si::socket 1927 :server #'one-result :daemon t))
(setq x (mapcar (lambda (x) (si::socket 1927 :host "localhost")) (make-list 
10)))
(mapcar (lambda (x) (format x "~s~%" (+ 10 (random 20)))) x)
(watch x)

=============================================================================

Take care,

> I think that it would be most desireable if you could "advertise" any aspect
> of GCL's capabilities at parallelism with appropriate one-page running
> examples for dummies like me.
> 
> For a great example of what I am talking about, see
> 
>   
> http://www.sbcl.org/manual/Waitqueue-condition-variables.html#Waitqueue%2fcondition%20variables
> 
>      (defvar *buffer-queue* (make-waitqueue))
>      (defvar *buffer-lock* (make-mutex :name "buffer lock"))
>      
>      (defvar *buffer* (list nil))
>      
>      (defun reader ()
>        (with-mutex (*buffer-lock*)
>          (loop
>           (condition-wait *buffer-queue* *buffer-lock*)
>           (loop
>            (unless *buffer* (return))
>            (let ((head (car *buffer*)))
>              (setf *buffer* (cdr *buffer*))
>              (format t "reader ~A woke, read ~A~%"
>                      *current-thread* head))))))
>      
>      (defun writer ()
>        (loop
>         (sleep (random 5))
>         (with-mutex (*buffer-lock*)
>           (let ((el (intern
>                      (string (code-char
>                               (+ (char-code #\A) (random 26)))))))
>             (setf *buffer* (cons el *buffer*)))
>           (condition-notify *buffer-queue*))))
>      
>      (make-thread #'writer)
>      (make-thread #'reader)
>      (make-thread #'reader)
> 
> I almost understood from that single example not only about readers and
> writers and mutex and buffers and locks and quiues and condition-waits but
> learned from the brief but lucid documentation about many of the sb-thread
> package primitives.
> 
> There is something about running examples of working parallelism that teach
> (to me anyway) far more than words.
> 
> Bob
> 
> 
> 
> 

-- 
Camm Maguire                                            address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




reply via email to

[Prev in Thread] Current Thread [Next in Thread]