ok, I got this benchmark down to 19 minutes. For reference, the Haskell benchmark took 2.8 times as long on my machine as it did on the Debian benchmark machine. So, dividing my time by 2.8, I got 405 seconds, or, almost 7 minutes. This is at least in the ballpark now. Here is the code. It was tough to get it down this fast:
Code: Select all
#!/usr/bin/newlisp
(setq
nThreads 503
nTransactions 50000000
channels (list)
start-time (time-of-day)
token "a" ltoken (length token)
)
(define (pass-token) (write write-to-pipe token ltoken))
(define (recv-token) (if (and (= (length token) (read read-from-pipe c ltoken)) (= c token)) true nil))
(define (worker id read-from-pipe write-to-pipe n)
(catch
(while (recv-token)
(-- n nThreads)
(if (< 0 n)
(pass-token)
(println (format "Done by id %d\nSeconds: %.2f" id (div (- (time-of-day) start-time) 1000)))
(throw nil))
(when (< n nThreads) (throw nil))))
(write write-to-pipe "b" 1))
;; make communication channels
(dotimes (i nThreads) (push (pipe) channels -1))
;; spawn workers
(dotimes (i nThreads)
(fork
(worker (+ 1 i) (channels i 0) (channels (% (+ 1 i) nThreads) 1) (+ nTransactions nThreads (- i) -1))))
;; put the token in the ring
(setq write-to-pipe (channels 0 1)) (pass-token)
(dotimes (i nThreads) (wait-pid -1 0))
(exit)
I tried using spawn and sync, but was getting segfaults. Also, I noticed sync was eating up almost 90% cpu time in the parent.
I'm looking at the sweet timings for Go and Haskell, even SBCL Lisp was able to do it in under 5 minutes.
I have heard from Linux and BSD kernel developers that pthreads API is the right way to go; the library itself is responsible for forking enough times so that the kernel can schedule threads on appropriate CPU's. I remember that is why Linus developed the "clone" API in the Linux kernel. And in OpenBSD, the rthreads implementation of pthreads is supposed to do this too.
If there is any way to speed this up, please show us in here! I did my best.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence. Nine months later, they left with a baby named newLISP. The women of the ivory towers wept and wailed. "Abomination!" they cried.