The Program below seems very inefficient. It takes as much as 28.980 GC time, in contrast 6.361 sec non-GC time, with SBCL 1.0.53.
(deftype vec3 () '(simple-array double-float (3)))
(declaim (inline make-vec3 vec3-zero
vec3-x vec3-y vec3-z
vec3-+))
(defun make-vec3 (x y z)
(declare (optimize (speed 3) (safety 0)))
(make-array 3 :element-type 'double-float
:initial-contents (list x y z)))
(defun vec3-zero ()
(make-vec3 0.0d0 0.0d0 0.0d0))
(defun vec3-x (x)
(declare (optimize (speed 3) (safety 0)))
(declare (type (simple-array double-float (3)) x))
(aref x 0))
(defun vec3-y (x)
(declare (optimize (speed 3) (safety 0)))
(declare (type (simple-array double-float (3)) x))
(aref x 1))
(defun vec3-z (x)
(declare (optimize (speed 3) (safety 0)))
(declare (type (simple-array double-float (3)) x))
(aref x 2))
(defun vec3-+ (a b)
(declare (optimize (speed 3) (safety 0)))
(make-vec3 (+ (vec3-x a) (vec3-x b))
(+ (vec3-y a) (vec3-y b))
(+ (vec3-z a) (vec3-z b))))
;; main
(defun image (x y)
(make-array (* x y) :element-type 'vec3 :initial-element (vec3-zero)))
(defun add (to from val)
(declare (type (simple-array vec3 (*)) to from)
(type vec3 val)
(optimize (speed 3) (safety 0)))
(let ((size (array-dimension to 0)))
(dotimes (i size)
(setf (aref to i) (vec3-+ (aref from i) val)))))
(defun main ()
(let ((to (image 800 800))
(x (make-vec3 1.0d0 1.0d0 1.0d0)))
(time (dotimes (i 200)
(add to to x)))
(print (aref to 0))))
time:
* (main)
Evaluation took:
39.530 seconds of real time
35.340237 seconds of total run time (25.945526 user, 9.394711 system)
[ Run times consist of 28.980 seconds GC time, and 6.361 seconds non-GC time. ]
89.40% CPU
83,778,297,762 processor cycles
46 page faults
6,144,014,656 bytes consed
#(200.0d0 200.0d0 200.0d0)
#(200.0d0 200.0d0 200.0d0)
Are there any approach to compute it in more efficient way, keeping the vec3 abstraction?
For example, implementing Worker/Wrapper transformation using macro can eliminate the vec3 conses.
As another way, making cons pool for vec3 will decrease the memory allocation.
Ideally, it would be nice that SBCL supports non-descriptor representations for some data structure, like vec3, as array elements.