gpt4 book ai didi

performance - Common Lisp,尤其是SBCL中线性代数的高效向量运算?

转载 作者:行者123 更新时间:2023-12-04 02:38:28 24 4
gpt4 key购买 nike

下面的程序似乎非常低效。它需要多达 28.980 次 GC 时间,相比之下,非 GC 时间为 6.361 秒,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))))

时间:
* (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)

有没有办法以更有效的方式计算它,保持 vec3 抽象?

例如,使用宏实现 Worker/Wrapper 转换可以消除 vec3 conses。

另一方面,为 vec3 制作 cons 池将减少内存分配。

理想情况下,SBCL 支持某些数据结构(如 vec3)的非描述符表示作为数组元素会很好。

最佳答案

我认为在这些情况下,使用宏可能是一个好主意。接下来,我总是犹豫声明(安全 0),它会带来非常非常小的性能提升,并且如果只有 defun 内部的代码以及调用 defun 的所有代码都不是绝对正确的,则会导致奇怪的行为。

我认为这里重要的是不要在 make-vec3 中创建一个新的列表对象。我附上了你的代码的一个有点快速和肮脏的优化。在我的机器上原始代码
跑进来

; cpu time (non-gc) 27.487818 sec user, 0.008999 sec system
; cpu time (gc) 17.334368 sec user, 0.001999 sec system
; cpu time (total) 44.822186 sec user, 0.010998 sec system
; real time 44.839858 sec
; space allocation:
; 0 cons cells, 45,056,000,000 other bytes, 0 static bytes

我的版本运行在
; cpu time (non-gc) 4.075385 sec user, 0.001000 sec system
; cpu time (gc) 2.162666 sec user, 0.000000 sec system
; cpu time (total) 6.238051 sec user, 0.001000 sec system
; real time 6.240055 sec
; space allocation:
; 8 cons cells, 8,192,030,976 other bytes, 0 static bytes

这是使用 Allegro。 YMMV 在其他 lisps 上。您提到了 vec3 数组的池化 conses/内存,我认为重用这些对象,即破坏性地修改它们,当您有机会这样做时是个好主意。在我的 lisp 上,一个 vec3 需要 64 个字节,这是相当多的……另一个有用的事情当然是调用分析器来查看时间花在哪里。此外,在这些数学重的问题中,数组引用和算术尽可能采用开放式编码非常重要。大多数 lisp 可以 (dissassemble 'my-function),如果这些操作确实是开放编码的或者是否调用了运行时,这给出了一个好主意。
(deftype vec3 () '(simple-array double-float (3)))

(declaim (optimize (speed 3) (debug 0) (safety 1)))

(defmacro make-vec3 (x y z)
`(let ((vec3
(make-array 3 :element-type 'double-float :initial-element 0.0d0)))
(setf (aref vec3 0) ,x
(aref vec3 1) ,y
(aref vec3 2) ,z)
vec3))


(defun vec3-zero ()
(make-vec3 0.0d0 0.0d0 0.0d0))

(defmacro vec3-x (x)
`(aref ,x 0))

(defmacro vec3-y (x)
`(aref ,x 1))

(defmacro vec3-z (x)
`(aref ,x 2))

(defun vec3-+ (a b)
(declare (type vec3 a b))
(make-vec3 (+ (vec3-x a) (vec3-x b))
(+ (vec3-y a) (vec3-y b))
(+ (vec3-z a) (vec3-z b))))

(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))
(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))))

关于performance - Common Lisp,尤其是SBCL中线性代数的高效向量运算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8356494/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com