通常の問題は、浮動小数点演算(行列乗算のような周囲のコードとは独立したdouble-floats)がconsesであることです。一般
このような場合にはSBCLで最初に行うべきこと:
をファイルにコードを入れてコンパイルし、それ
コンパイラは、出力その1つのコンパイル与えられた最適化問題の多くは、速度のために。あなたはメモを調べ、あなたができることを見る必要があります。
たとえば、LOOP
の合計にはタイプ情報がありません。
sum変数の型を宣言する実際にはLOOP
の構文があります。 SBCLがそれを利用するかどうかは分かりません。
(loop repeat 10
sum 1.0d0 of-type double-float)
SBCL 1.3。
* (compile-file "/tmp/test.lisp")
; compiling file "/tmp/test.lisp" (written 13 DEC 2015 11:34:26 AM):
; compiling (DEFUN MATRIX-MUL ...)
; file: /tmp/test.lisp
1)
; in: DEFUN MATRIX-MUL
; (SETF (AREF DEST I)
; (LOOP FOR J BELOW COLS
; SUM (THE DOUBLE-FLOAT (* # #))))
; --> LET* FUNCALL SB-C::%FUNCALL (SETF AREF)
; ==>
; (SB-KERNEL:HAIRY-DATA-VECTOR-SET ARRAY SB-INT:INDEX SB-C::NEW-VALUE)
;
; note: unable to
; avoid runtime dispatch on array element type
; due to type uncertainty:
; The first argument is a (VECTOR DOUBLE-FLOAT), not a SIMPLE-ARRAY.
2)
; (AREF MATRIX I J)
; --> LET*
; ==>
; (SB-KERNEL:HAIRY-DATA-VECTOR-REF ARRAY SB-INT:INDEX)
;
; note: unable to
; avoid runtime dispatch on array element type
; due to type uncertainty:
; The first argument is a (ARRAY DOUBLE-FLOAT (* *)), not a SIMPLE-ARRAY.
3)
; (AREF VECTOR J)
; ==>
; (SB-KERNEL:HAIRY-DATA-VECTOR-REF ARRAY SB-INT:INDEX)
;
; note: unable to
; avoid runtime dispatch on array element type
; due to type uncertainty:
; The first argument is a (VECTOR DOUBLE-FLOAT), not a SIMPLE-ARRAY.
4)
012:コードのための32ビットARMに
5)
; --> BLOCK LET SB-LOOP::WITH-SUM-COUNT LET SB-LOOP::LOOP-BODY TAGBODY WHEN IF
; --> >= OR LET IF OR THE = IF
; ==>
; (= SB-C::X SB-C::Y)
;
; note: unable to open code because: The operands might not be the same type.
6)
; (DOTIMES (I ROWS)
; (SETF (AREF DEST I)
; (LOOP FOR J BELOW COLS
; SUM (THE DOUBLE-FLOAT #))))
; --> DO BLOCK LET TAGBODY UNLESS IF >= IF
; ==>
; (< SB-C::X SB-C::Y)
;
; note: forced to do static-fun Two-arg-< (cost 53)
; unable to do inline fixnum comparison (cost 4) because:
; The second argument is a INTEGER, not a FIXNUM.
; unable to do inline (signed-byte 32) comparison (cost 6) because:
; The second argument is a INTEGER, not a (SIGNED-BYTE 32).
; etc.
7)
; (LOOP FOR J BELOW COLS
; SUM (THE DOUBLE-FLOAT (* (AREF MATRIX I J) (AREF VECTOR J))))
; --> BLOCK LET SB-LOOP::WITH-SUM-COUNT LET SB-LOOP::LOOP-BODY TAGBODY WHEN IF
; --> >= OR LET > IF
; ==>
; (> SB-C::X SB-C::Y)
;
; note: forced to do static-fun Two-arg-> (cost 53)
; unable to do inline fixnum comparison (cost 4) because:
; The second argument is a REAL, not a FIXNUM.
; unable to do inline (signed-byte 32) comparison (cost 6) because:
; The second argument is a REAL, not a (SIGNED-BYTE 32).
; etc.
8)
; --> BLOCK LET SB-LOOP::WITH-SUM-COUNT LET SB-LOOP::LOOP-BODY TAGBODY SETQ THE
; ==>
; (+ #:LOOP-SUM-8 (THE DOUBLE-FLOAT (* (AREF MATRIX I J) (AREF VECTOR J))))
;
; note: forced to do static-fun Two-arg-+ (cost 53)
; unable to do inline float arithmetic (cost 2) because:
; The first argument is a NUMBER, not a DOUBLE-FLOAT.
; The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES DOUBLE-FLOAT
; &REST T).
;
; note: doing float to pointer coercion (cost 13), for:
; the second argument of static-fun Two-arg-+
;
; compilation unit finished
; printed 10 notes
また見てみたいことがありますリスプマトリックスでBLASとLAPACKを呼び出す行列関数を実装しています。あなたはおそらくそれらがはるかに高速であることがわかります。特に、行列のサイズが大きくなるにつれて、 –
@EliasMårtenson私がBLで直接行っているのは、BLASにバインドしたくないからです。私が扱っているサイズ(〜100)は重い砲兵を保証するものではなく、Windows(CygwinやMGWin)からのBLASへのバインディングも別の話です。 – mobiuseng