mandelbrot Lisp SBCL #3 program
source code
;; The Computer Language Benchmarks Game
;; https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
;;;
;;; resubmitted by Wade Humeniuk (Fix Stream Problem)
;;; resubmitted by Jon Smith (Remove silly assertion causing it to break on 16000 size)
;;; re-resubmitted by Jon Smith (with a silly hack to make it parallel).
;;; Original contributed by Yannick Gingras
;;;
;;; To compile
;;; sbcl --load mandelbrot.lisp --eval "(save-lisp-and-die \"mandelbrot.core\" :purify t :toplevel (lambda () (main) (quit)))"
;;; To run
;;; sbcl --noinform --core mandelbrot.core %A
(defun render (size stream)
(declare (type fixnum size) (stream stream)
(optimize (speed 3) (safety 0) (debug 0)))
(let* ((code 0)
(bit 0)
(zr 0.0d0)
(zi 0.0d0)
(tr 0.0d0)
(delta (/ 2d0 size))
(base-real -1.5d0)
(base-imag -1.0d0)
(buffer (make-array (* size (ceiling size 8)) :element-type '(unsigned-byte 8)))
(index 0))
(declare (type (unsigned-byte 8) code )
(type double-float zr zi tr base-real base-imag delta)
(type fixnum index bit))
(dotimes (y size)
(setf base-imag (- 1.0d0 (* delta y)))
(dotimes (x size)
(setf base-real (+ -1.5d0 (* delta x))
zr base-real
zi base-imag)
(setf code
(if (dotimes (n 50)
(when (< 4.0d0 (+ (* zr zr) (* zi zi)))
(return t))
(setf tr (+ (* zr zr) (- (* zi zi)) base-real)
zi (+ (* 2.0d0 zr zi) base-imag)
zr tr))
(ash code 1)
(logior (ash code 1) #x01)))
(when (= (incf bit) 8)
(setf (aref buffer index) code
bit 0 code 0)
(incf index))))
(write-sequence buffer stream)))
(defun par-render (size stream)
(declare (type fixnum size) (stream stream)
(optimize (speed 3) (safety 0) (debug 0)))
(let* ((buffer (make-array (* size (ceiling size 8)) :element-type '(unsigned-byte 8)))
(quarter-size (ceiling size 4))
(quarter-array (ceiling (the (unsigned-byte 32) (* size size)) 32)))
(labels ((render-sub (y-start y-end index)
(let ((code 0)
(bit 0)
(zr 0.0d0) (zi 0.0d0) (tr 0.0d0)
(delta (/ 2d0 size))
(base-real -1.5d0) (base-imag -1.0d0))
(declare (type (unsigned-byte 8) code)
(type double-float zr zi tr base-real base-imag delta)
(type fixnum index bit))
(do ((y y-start (1+ y)))
((= y y-end))
(declare (type (unsigned-byte 32) y))
(setf base-imag (- 1.0d0 (* delta y)))
(dotimes (x size)
(setf base-real (+ -1.5d0 (* delta x))
zr base-real
zi base-imag)
(setf code
(if (dotimes (n 50)
(when (< 4.0d0 (+ (* zr zr) (* zi zi)))
(return t))
(setf tr (+ (* zr zr) (- (* zi zi)) base-real)
zi (+ (* 2.0d0 zr zi) base-imag)
zr tr))
(ash code 1)
(logior (ash code 1) #x01)))
(when (= (incf bit) 8)
(setf (aref buffer index) code
bit 0
code 0)
(incf index))
)))))
(let (threads)
(dotimes (i 4)
(let ((start (* i quarter-size))
(end (* (+ i 1) quarter-size))
(idx (* i quarter-array)))
(push (sb-thread:make-thread (lambda () (render-sub start end idx))) threads)))
(dolist (thread threads)
(sb-thread:join-thread thread)))
(write-sequence buffer stream))))
(defun main ()
(declare (optimize (speed 0) (safety 3)))
(let* ((args sb-ext:*posix-argv*)
(n (parse-integer (second args))))
(with-open-stream (stream (sb-sys:make-fd-stream (sb-sys:fd-stream-fd sb-sys:*stdout*)
:element-type :default
:buffering :full
:output t :input nil))
(format stream "P4~%~d ~d~%" n n)
#+sb-thread(par-render n stream)
#-sb-thread(render n stream)
(force-output stream))))
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
SBCL 2.0.4
Fri, 22 May 2020 00:05:45 GMT
MAKE:
cp: 'mandelbrot.sbcl-3.sbcl' and './mandelbrot.sbcl-3.sbcl' are the same file
SBCL built with: /usr/local/bin/sbcl --userinit /dev/null --batch --eval '(load "mandelbrot.sbcl-3.sbcl_compile")'
### START mandelbrot.sbcl-3.sbcl_compile
(handler-bind ((sb-ext:defconstant-uneql (lambda (c) (abort c)))) (require :sb-concurrency) (load (compile-file "mandelbrot.sbcl-3.sbcl" ))) (save-lisp-and-die "sbcl.core" :purify t)
### END mandelbrot.sbcl-3.sbcl_compile
; compiling file "/home/dunham/8000-benchmarksgame/bench/mandelbrot/mandelbrot.sbcl-3.sbcl" (written 26 APR 2018 12:48:32 PM):
; compiling (DEFUN RENDER ...)
; compiling (DEFUN PAR-RENDER ...)
; compiling (DEFUN MAIN ...)
; wrote /home/dunham/benchmarksgame_quadcore/mandelbrot/tmp/mandelbrot.sbcl-3.fasl
; compilation finished in 0:00:00.175
### START mandelbrot.sbcl-3.sbcl_run
(main) (quit)
### END mandelbrot.sbcl-3.sbcl_run
4.79s to complete and log all make actions
COMMAND LINE:
/usr/local/bin/sbcl --noinform --core sbcl.core --userinit /dev/null --load mandelbrot.sbcl-3.sbcl_run 16000
(BINARY) PROGRAM OUTPUT NOT SHOWN