From: Patrick Stein <sbclhelp@nk...>  20090622 23:24:41

I am using SBCL 1.0.29 on an x86 MacBook Pro. I am, at this point, simply trying to multiply a matrix and a vector. The matrix is three rows and four columns, the vector is three columns. I was trying to be nice and declare the types... and eventually to crank down the safety and crank up the speed. But, for now, I was just trying to declare the types. ====================================================== (declaim (ftype (function ((array singlefloat (3 4)) (array singlefloat 3)) (array singlefloat 3)) mv*)) (defun mv* (matrix vector) (let ((ret (makearray 3 :initialelement 0.0s0 :elementtype 'singlefloat))) (loop for jj from 0 below 3 do (setf (svref ret jj) (+ (aref matrix jj 3) (loop for ii from 0 below 3 summing (* (aref vector ii) (aref matrix jj ii)))))) ret)) ====================================================== I get a five notes about deleting unreachable code. All of the code looks reachable to me, but I don't know how much loop or setf munge that on me. The one that I'm trying to tackle first is the warning: ; (SETF (SVREF RET JJ) ; (+ (AREF MATRIX JJ 3) ; (LOOP FOR II FROM 0 BELOW 3 ; SUMMING (* (AREF VECTOR II) (AREF MATRIX JJ II))))) ; > SBKERNEL:%SVSET SBKERNEL:%ASET ; ==> ; (THE SIMPLEVECTOR RET) ; ; caught WARNING: ; Asserted type SIMPLEVECTOR conflicts with derived type ; (VALUES (SIMPLEARRAY SINGLEFLOAT (3)) &OPTIONAL). ; See also: ; The SBCL Manual, Node "Handling of Types" Now, the section on "Handling of Types" in the manual was an interesting read, but I didn't find anything that helped me there. In the section of the manual about understanding compiler messages, it seems like this is complaining that I am trying to declare the return type of the (SETF ...) to be some type. I don't think I care what type that is. Basically, I cannot read the above enough to tell where it is getting an asserted type... and for what expression/variable etc. The deleting unreachable code messages seem to cover just about the whole function, so I'm assuming that they will go away if I manage to tackle the above warning. But, I'll include those messages at the end here for completeness. Any help would be much appreciated.... Apologies if this has already been answered a few times... I can't figure out how to search the sbclhelp archives any more. Thanks, Patrick ; file: /private/var/tmp/tmp.4.HBL80J.lisp ; in: DEFUN MV* ; (SETF (SVREF RET JJ) ; (+ (AREF MATRIX JJ 3) ; (LOOP FOR II FROM 0 BELOW 3 ; SUMMING (* (AREF VECTOR II) (AREF MATRIX JJ II))))) ; > SBKERNEL:%SVSET SBKERNEL:%ASET ; ==> ; JJ ; ; note: deleting unreachable code ; (AREF VECTOR II) ; ==> ; VECTOR ; ; note: deleting unreachable code ; (LOOP FOR II FROM 0 BELOW 3 ; SUMMING (* (AREF VECTOR II) (AREF MATRIX JJ II))) ; > BLOCK LET LET SBLOOP::LOOPBODY TAGBODY WHEN IF >= ; ==> ; II ; ; note: deleting unreachable code ; (+ (AREF MATRIX JJ 3) ; (LOOP FOR II FROM 0 BELOW 3 ; SUMMING (* (AREF VECTOR II) (AREF MATRIX JJ II)))) ; ; note: deleting unreachable code ; (LET ((RET (MAKEARRAY 3 :INITIALELEMENT 0.0 :ELEMENTTYPE 'SINGLEFLOAT))) ; (LOOP FOR JJ FROM 0 BELOW 3 ; DO (SETF (SVREF RET JJ) ; (+ (AREF MATRIX JJ 3) ; (LOOP FOR II FROM 0 BELOW 3 ; SUMMING #)))) ; RET) ; ==> ; RET ; ; note: deleting unreachable code 
From: Patrick Stein <sbclhelp@nk...>  20090623 01:00:28
Attachments:
Message as HTML

On Mon, Jun 22, 2009 at 6:40 PM, Richard M Kreuter <kreuter@...>wrote: > SVREF only works on SIMPLEVECTORS. A SIMPLEVECTOR is > >  a vector that is not displaced to another array, has no fill pointer, >  is not expressly adjustable and is able to hold elements of any type > > Your RET is a vector of SINGLEFLOATs, not a SIMPLEVECTOR. Thank you... that did indeed, get me past that hump. =========================== (declaim (ftype (function ((array singlefloat (3 4)) (vector singlefloat 3)) (vector singlefloat 3)) mv*)) (defun mv* (matrix vector) (declare (optimize (speed 3) (safety 0))) (let ((ret (makearray 3 :initialelement 0.0s0 :elementtype 'singlefloat))) (loop for jj from 0 below 3 do (setf (aref ret jj) (+ (aref matrix jj 3) (loop for ii from 0 below 3 summing (* (aref vector ii) (aref matrix jj ii)))))) ret)) =========================== Now, to beat it up until it likes a higher speed setting. Most of the notes I get from (speed 2) (safety 0) are understandable. But, I don't have any idea what the first one is complaining about: ; file: /private/var/tmp/tmp.3.87YzPd.lisp ; in: DEFUN MV* ; (AREF MATRIX JJ 3) ; > LET* ; ==> ; (SBKERNEL:HAIRYDATAVECTORREF ARRAY SBINT:INDEX) ; ; note: unable to ; avoid runtime dispatch on array element type ; due to type uncertainty: ; The first argument is a (ARRAY SINGLEFLOAT (3 4)), not a SIMPLEARRAY. As you mentioned, a simplearray would have type uncertainty. But, shouldn't (array singlefloat (3 4)) be fairly typecertain? Thanks, Patrick 
From: Patrick Stein <sbclhelp@nk...>  20090623 01:04:18

Okay, so some of my confusion is that: (lambda (x) (declare (type (simplevector singlefloat 3) x)) (aref x 0)) and (lambda (x) (declare (type (simplevector singlefloat (3)) x)) (aref x 0)) are different. I hadn't realized that before. That was definitely my fault. Everything else seems to be normal stuff that I'd expect because I hadn't put and (the ...) or (coerce ...) stuff around the math parts. Thanks, Patrick 
From: Nikodemus Siivola <nikodemus@ra...>  20090623 18:56:31

2009/6/23 Patrick Stein <sbclhelp@...>: > (declaim (ftype (function ((array singlefloat (3 4)) > (vector singlefloat 3)) > (vector singlefloat 3)) mv*)) > (defun mv* (matrix vector) > (declare (optimize (speed 3) (safety 0))) > (let ((ret (makearray 3 :initialelement 0.0s0 > :elementtype 'singlefloat))) > (loop for jj from 0 below 3 > do (setf (aref ret jj) > (+ (aref matrix jj 3) > (loop for ii from 0 below 3 > summing (* (aref vector ii) > (aref matrix jj ii)))))) > ret)) If you want speed, there is one you seriously want to do here: use a onedimensional simplearray for the matrix: (simplearray singlefloat (12)). The reason is that a multidimensional array is represented with an array header object and a data vector: every array access will have one more memory indirect. (There are ways of making multidimensional arrays faster in SBCL, by using either dope vectors or changing the representation  but noone is working on either of those at the moment, so...) Cheers,  Nikodemus 
From: Richard M Kreuter <kreuter@pr...>  20090623 02:42:13

Patrick Stein writes: > (declaim (ftype (function ((array singlefloat (3 4)) > (array singlefloat 3)) > (array singlefloat 3)) mv*)) > > (defun mv* (matrix vector) > (let ((ret (makearray 3 :initialelement 0.0s0 > :elementtype 'singlefloat))) > (loop for jj from 0 below 3 > do (setf (svref ret jj) > (+ (aref matrix jj 3) > (loop for ii from 0 below 3 > summing (* (aref vector ii) > (aref matrix jj ii)))))) > ret)) SVREF only works on SIMPLEVECTORS. A SIMPLEVECTOR is  a vector that is not displaced to another array, has no fill pointer,  is not expressly adjustable and is able to hold elements of any type Your RET is a vector of SINGLEFLOATs, not a SIMPLEVECTOR.  Richard 
From: Patrick Stein <sbclhelp@nk...>  20090623 14:13:46

On Tue, Jun 23, 2009 at 4:23 AM, Nikodemus Siivola<nikodemus@...> wrote: > If you want speed, there is one you seriously want to do here: use a > onedimensional simplearray for the matrix: (simplearray > singlefloat (12)). The reason is that a multidimensional array is > represented with an array header object and a data vector: every array > access will have one more memory indirect. Interesting. I will have to try it. But, getting the type declarations correct improved my speed by a factor of eleven. I can do t welve million iterations of this function in a second now. Interestingly, with the type information in there, it is very slightly slower with (speed 3) (safety 0) than with the defaults. With the defaults, I can do four million iterations in 0.334 seconds. With (speed 3) (safety 0), it takes 0.401 seconds. *shrug* Full details (and how Clozure and CLisp compared on the same machine): http://nklein.com/2009/06/optimizinglispsomemore/ Thanks for all the help, Patrick 
From: Nikodemus Siivola <nikodemus@ra...>  20090624 07:07:39

2009/6/23 Patrick Stein <sbclhelp@...>: > Interestingly, with the type information in there, it is very slightly > slower with (speed 3) (safety 0) than with the defaults. With the > defaults, I can do four million iterations in 0.334 seconds. With > (speed 3) (safety 0), it takes 0.401 seconds. *shrug* This can be due to eg. bad loop alignment, but without checking the disassembly its impossible to tell. Cheers,  Nikodemus 