<?xml version="1.0"?>
<rss version="0.92">
 <channel>
  <title>Nikodemus Siivola</title>
  <description>Curios, oddities, vagaries and anomalies
-- all to amuse the old and delight the young. Lisp hacks sold during
intermission.</description>
  <link>http://random-state.net/</link>
  <item>
  <title>Et Tu, Nikodemus</title>
   <category>hacking</category>
   <link>http://random-state.net/log/3467207496.html</link>
   <pubDate>Sat, 14 Nov 2009 19:11:36 +0300</pubDate>
   <description>
&lt;p&gt;Inspired by &lt;a
href="http://www.method-combination.net/blog/archives/2009/11/13/gone-to-github.html"&gt;Nathan&lt;/a&gt;,
I decided to put some of my not-hosted-anywhere things up on &lt;a
href="http://github.com/nikodemus"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This includes &lt;a
href="http://github.com/nikodemus/raylisp"&gt;raylisp&lt;/a&gt; and &lt;a
href="http://github.com/nikodemus/sb-cga"&gt;sb-cga&lt;/a&gt;. Neither is
released or supported in any shape or form, but since it turns out my
yesterday's snapshot was broken on x86, this is easier than making new
snapshots and less embarassing than letting people play with
known-broken snapshots...&lt;/p&gt;
  </description>
  </item>
<item>
  <title>Pretty Pictures</title>
   <category>hacking</category>
   <link>http://random-state.net/log/3467117369.html</link>
   <pubDate>Fri, 13 Nov 2009 18:09:29 +0300</pubDate>
   <description>
&lt;p&gt;&lt;i&gt;Update 2009-11-14: since the snapshot linked below turned out to
be broken on x86, you may be better off with the &lt;a
href="http://random-state.net/log/3467207496.html"&gt;git repos&lt;/a&gt;
instead.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;My first ever Common Lisp project was a raytracer. Unsurprisingly,
it wasn't too great. Over time I started thinking about how I would
make one that was more lispy, and during last couple of years I've
been hacking on one every once and a while.&lt;/p&gt;

&lt;p&gt;
 &lt;a href="http://random-state.net/images/raylisp-dragons-2009-11-13-full.png"
  &lt;img src="http://random-state.net/images/raylisp-dragons-2009-11-13-small.png"
       class="framed"
       width="342"
       height="350"
       alt="Stanford Dragon"
       title="Stanford Dragon"&gt;&lt;/img&gt;
 &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;It's called &lt;a
href="http://random-state.net/files/raylisp-2009-11-13.tar.gz"&gt;Raylisp&lt;/a&gt;,
and while I'm not planning on ever properly releasing it -- this is
purely a personal toy project -- I figured I might still make a
snapshop available: it may prove useful to someone wanting to do
something like this in earnest.&lt;/p&gt;

&lt;p&gt;The tarball contains:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Snapshop of another work-in-progress: SB-CGA, a computer graphics
     algebra library for SBCL -- most suited for x86-64, since there
     it implements things like matrix multiplication using SIMD
     instructions. Raylisp uses it, but unlike Raylisp this one may
     even see a release some day...&lt;/li&gt;
 &lt;li&gt;Raylisp itself, including:
  &lt;ul&gt;
   &lt;li&gt;reasonably efficient KD-tree construction and traversal code&lt;/li&gt;
   &lt;li&gt;very very hacky code for reading subsets of .ply and .obj
       files&lt;/li&gt;
   &lt;li&gt;basic raytracing stuff&lt;/li&gt;
   &lt;li&gt;a simple CLIM frontend on top of the raytracing library&lt;/li&gt;
  &lt;/ul&gt;
 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
 &lt;a href="http://random-state.net/images/raylisp-metal-2009-11-13-full.png"
  &lt;img src="http://random-state.net/images/raylisp-metal-2009-11-13-small.png"
       class="framed"
       width="342"
       height="350"
       alt="Metal balls"
       title="Metal balls"&gt;&lt;/img&gt;
 &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;In addition to the KD-tree code, which may be worth stealing and
polishing off, I'm putting this up to demonstrate some techniques
which may be non-obvious to new-but-performance-conscious Lisp
hackers: stack allocation (all over the place), using CLOS objects for
the parts that need flexibility and closures for the parts that need
to be fast (rendering protocol), and packing data into specialized
vectors to avoid GC overhead (KD tree construction.)&lt;/p&gt;

&lt;p&gt;(Last time I touched this code was in August, so all the details
are not too fresh on my mind -- hence the vague tone in this post.  I
had inteded to do this then, but didn't get around to it until
now.)&lt;/p&gt;

&lt;p&gt;All the code is under MIT-style license, as usual.&lt;p&gt;
  </description>
  </item>
<item>
  <title>MAKE-INSTANCE optimizations</title>
   <category>hacking</category>
   <link>http://random-state.net/log/3455254209.html</link>
   <pubDate>Mon, 29 Jun 2009 11:50:09 +0300</pubDate>
   <description>
&lt;p&gt;SBCL has always had a fairly efficient &lt;tt&gt;MAKE-INSTANCE&lt;/tt&gt; -- as
long as the class argument is a quoted symbol and all the keywords in
initargs are constant as well.&lt;/p&gt;

&lt;p&gt;This is due to what are called &lt;i&gt;ctors&lt;/i&gt;. Very briefly, a call
such as&lt;/p&gt;

&lt;pre&gt;(make-instance 'point :x x :y y)&lt;/pre&gt;

&lt;p&gt;is transformed into something along the lines of&lt;/p&gt;

&lt;pre&gt;(let ((#:ctor (load-time-value (ensure-ctor 'foo :x :y))))
  (funcall #:ctor x y))&lt;/pre&gt;

&lt;p&gt;where &lt;tt&gt;CTOR&lt;/tt&gt; is a funcallable instance. The first time it is
called, an optimized constructor is generated, saved as the
funcallable instance function, and finally called with the provided
arguments. Later calls get the optimized constructor ready made.&lt;/p&gt;

&lt;p&gt;There are multiple efficiency gains here: initargs can be checked
for validity at compile time, and (assuming certain things hold true
about the metaclass of the class and its methods) essentially the
whole &lt;tt&gt;MAKE-INSTANCE -&gt; ALLOCATE-INSTANCE | INITIALIZE-INSTANCE -&gt;
SHARED-INITIALIZE&lt;/tt&gt; call tree can be open coded, and slot accesses
can be performed using &lt;tt&gt;STANDARD-INSTANCE-ACCESS&lt;/tt&gt; with constant
slot locations. This all works with class redefinitions as
&lt;i&gt;ctors&lt;/i&gt; are updated automatically.&lt;/p&gt;

&lt;p&gt;Unfortunately, this made the performance of non-constant class arguments
to &lt;tt&gt;MAKE-INSTANCE&lt;/tt&gt; extremely unattractive in comparison: 10-100 times
slower is fairly typical. Ouch!&lt;/p&gt;

&lt;p&gt;At ELS 2009 Didier Verna asked if we could do something similar for
the non-constant case as well. Turns out we can:&lt;/p&gt;

&lt;pre&gt;(make-instance class :x x :y y)&lt;/pre&gt;

&lt;p&gt;can become something like&lt;/p&gt;

&lt;pre&gt;(let* ((#:cache (load-time-value (cons 'ctor-cache nil)))
       (#:store (cdr #:cache)))
  (multiple-value-bind (#:ctor #:new-store)
      (ensure-cached-ctor class :x :y #:store)
    (setf (cdr #:cache) #:new-store)
    (funcall #:ctor x y)))&lt;/pre&gt;

&lt;p&gt;where the ctor corresponding to the class argument is first looked
for in the cache: if it is not found a new one is generated and
cached.&lt;/p&gt;

&lt;p&gt;This was implemented in SBCL 1.0.29.41; now the non-constant class
arguments performs much better, being roughly only 1.15-1.25 times
slower than the constant ones. Hopefully this will make a real
difference in some applications out there!&lt;/p&gt;

&lt;p&gt;A bit later another ctor optimization improvement was implemented,
improving cases where the full open coding could not be done due to
defined methods, but where we are still able to check initargs at
compile time and replace the &lt;tt&gt;MAKE-INSTANCE&lt;/tt&gt; generic function
call with a slightly faster normal function call to a simplified
constructor function: this makes such calls 4-10 times slower than the
fast path, but still considerably faster than the worst case
scenario.&lt;/p&gt;

&lt;p&gt;The message to take home is actually not about SBCL optimizations
-- as much as I like to talk about them: I think ctors are an
excellent example of compiler macros doing inline caching and
specialization. A nice technique that could probably be used more
often than it is.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note&lt;/b&gt;: SBCL inherited its ctor optimizations from CMUCL: they
are the work of the estimable Gerd Moellmann. Things described above
do not replace his work, just extend it around the edges.  Those
interested in the gory details can look at &lt;tt&gt;src/pcl/ctor.lisp&lt;/tt&gt;
in the SBCL source tree.&lt;/p&gt;
  </description>
  </item>
<item>
  <title>Vim and SBCL</title>
   <category>hacking</category>
   <link>http://random-state.net/log/3453226588.html</link>
   <pubDate>Sat, 6 Jun 2009 00:36:28 +0300</pubDate>
   <description>
&lt;p&gt;Disclaimer: I don' use vim. However, there was a question on
sbcl-devel about how to make &lt;tt&gt;ED&lt;/tt&gt; use the console vim, and I
thought someone not on sbcl-devel readers might get a kick out of
this:&lt;/p&gt;

&lt;pre&gt;(require :sb-introspect)

(define-alien-routine system int (command c-string))

(defun namestring-for-vim (thing)
  (when thing
    (typecase thing
      (pathname
       (native-namestring (translate-logical-pathname thing) :as-file t))
      (string
       thing)
      (t
       (let* ((source
               (sb-introspect:find-definition-source (fdefinition thing)))
              (pathname
               (sb-introspect:definition-source-pathname source))
              (offset
               (or (sb-introspect:definition-source-character-offset source)
                   0)))
         (unless pathname
           (error "Don't know where the definition of ~S is, sorry." thing))
         (format nil "-c \"goto ~A\" ~A"
                 offset
                 (namestring-for-vim pathname)))))))

(defun ed-in-vim (thing)
  (system (format nil "vim~@[ ~A~]" (namestring-for-vim thing))))

(push 'ed-in-vim *ed-functions*)&lt;/pre&gt;

&lt;p&gt;Given this, &lt;tt&gt;(ED 'CONS)&lt;/tt&gt; does the right thing, assuming SBCL sources
are in place.&lt;/p&gt;
  </description>
  </item>
<item>
  <title>Condition Style Guide</title>
   <category>hacking</category>
   <link>http://random-state.net/log/3453016738.html</link>
   <pubDate>Wed, 3 Jun 2009 14:18:58 +0300</pubDate>
   <description>
&lt;p&gt;I don't claim this to be authoritative, but I'd be very interested
in hearing any opposing views. So: a quick style guide for using the
Common Lisp condition system -- I'm eliding restarts for now,
though.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Signalling Conditions&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;tt&gt;#'ERROR&lt;/tt&gt; to signal conditions inheriting from
&lt;tt&gt;SERIOUS-CONDITION&lt;/tt&gt;. This includes all subclasses or
&lt;tt&gt;ERROR&lt;/tt&gt;. &lt;tt&gt;SERIOUS-CONDITION&lt;/tt&gt; is a convention that means
"this will land you in the debugger if not handled", which is what
&lt;tt&gt;#'ERROR&lt;/tt&gt; ensures.&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Inherit from &lt;tt&gt;ERROR&lt;/tt&gt; if unwinding from the error leaves the
system in a consistent state. Subclasses of &lt;tt&gt;ERROR&lt;/tt&gt; mean "oops,
we have a problem, but it's OK to unwind."&lt;/li&gt;

&lt;li&gt;Inherit from &lt;tt&gt;SERIOUS-CONDITION&lt;/tt&gt;, not &lt;tt&gt;ERROR&lt;/tt&gt;, if
the system is messed up somehow, and/or requires either human
intervention or special knowledge about the situation to resolve:
&lt;tt&gt;SERIOUS-CONDITIONs&lt;/tt&gt; that are not &lt;tt&gt;ERRORs&lt;/tt&gt; mean that
"something is deeply wrong and you should know what you are doing if
you are going to resolve this."&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Use &lt;tt&gt;#'WARN&lt;/tt&gt; to signal conditions inheriting from
&lt;tt&gt;WARNING&lt;/tt&gt;. This includes all subclasses of
&lt;tt&gt;STYLE-WARNING&lt;/tt&gt;. &lt;tt&gt;WARNING&lt;/tt&gt; is a convention that means
"this will print out a warning if not muffled, and you can muffle this
with the &lt;tt&gt;MUFFLE-WARNING&lt;/tt&gt; restart", which is what
&lt;tt&gt;#'WARN&lt;/tt&gt; ensures.

&lt;ul&gt;

&lt;li&gt;Inherit from &lt;tt&gt;STYLE-WARNING&lt;/tt&gt; if muffling the warning should
be fine pretty much whenever.&lt;/li&gt;

&lt;li&gt;Inherit from &lt;tt&gt;WARNING&lt;/tt&gt;, not &lt;tt&gt;STYLE-WARNING&lt;/tt&gt;, if
muffling the warning is OK only if the muffler knows how to deal with
the specific warning: otherwise someone should be made aware of the
situation, which is what warnings are for.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Otherwise use &lt;tt&gt;#'SIGNAL&lt;/tt&gt;, and don't expect others to handle
your conditions unless you document them as part of your API.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Handling Conditions&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Learn the difference between &lt;a
href="http://www.lispworks.com/documentation/HyperSpec/Body/m_handle.htm"&gt;&lt;tt&gt;HANDLER-BIND&lt;/tt&gt;&lt;/a&gt;
and &lt;a
href="http://www.lispworks.com/documentation/HyperSpec/Body/m_hand_1.htm"&gt;&lt;tt&gt;HANDLER-CASE&lt;/tt&gt;&lt;/a&gt;. Short
version: &lt;tt&gt;HANDLER-CASE&lt;/tt&gt; always unwinds, with
&lt;tt&gt;HANDLER-BIND&lt;/tt&gt; you can eg. log the condition without handling
it, or decide whether to unwind or not after inspecting the condition
in more detail.&lt;/p&gt;

&lt;p&gt;Don't handle arbitrary conditions: a lower layer using
&lt;tt&gt;#'SIGNAL&lt;/tt&gt; as a communication mechanism will break if you do
that.&lt;/p&gt;

&lt;p&gt;Don't muffle arbitary &lt;tt&gt;WARNINGs&lt;/tt&gt; that are not
&lt;tt&gt;STYLE-WARNINGS&lt;/tt&gt;. A full warning can still be muffled, but only
if it's one you &lt;i&gt;know&lt;/i&gt; to be harmless in your case. Otherwise, a full
warning should either result in a fail-stop, or logging the condition
somewhere -- depending on the kind of application you are developing.&lt;/p&gt;

&lt;p&gt;Don't handle arbitary &lt;tt&gt;SERIOUS-CONDITIONs&lt;/tt&gt; that are not
&lt;tt&gt;ERRORs&lt;/tt&gt;: if you cannot pop up a debugger and don't know
exactly how to deal with this specific condition, the right answer is
to crash -- of course preferably with an error message, but don't
expect that to work properly: maybe the serious condition was about
corruption in the IO system...&lt;/p&gt;

&lt;p&gt;If you just want to ensure the application doesn't enter the
debugger, bind &lt;tt&gt;*DEBUGGER-HOOK*&lt;/tt&gt; appropriately -- but be aware
that &lt;tt&gt;#'BREAK&lt;/tt&gt; circumvents &lt;tt&gt;*DEBUGGER-HOOK*&lt;/tt&gt;: if that's
a danger, refer to the documentation of the implementation you are
using -- most provide a way to hook into &lt;tt&gt;#'BREAK&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Happy hacking.&lt;/p&gt;
  </description>
  </item>
<item>
  <title>Performance, Benchmark of the Day</title>
   <category>hacking</category>
   <link>http://random-state.net/log/3452921796.html</link>
   <pubDate>Tue, 2 Jun 2009 11:56:36 +0300</pubDate>
   <description>
&lt;p&gt;In reference to &lt;a
href="http://metamatix.org/~ocaml/price-of-abstraction.html"&gt;The Price
of Abstraction&lt;/a&gt; and &lt;a
href="http://www.reddit.com/r/programming/comments/8oz2b/c_encourages_the_usage_of_the_most_sophisticated/"&gt;the
associated Reddit comments&lt;/a&gt;:&lt;p&gt;

&lt;p&gt;On my laptop C++ versions 1 and 2 run in 2.139s and 2.410s
respectively (user+sys), and the direct Common Lisp translations using
double floats and native complexes run in 3.692s and 4.594s on
SBCL. See: &lt;a href="http://random-state.net/files/mandelbench.lisp"&gt;mandelbench.lisp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I haven't investigated the source of the performance difference,
but given that the SBCL generates -- at a quick glance -- reasonable
looking code for both, I believe the difference comes from something
lacking in loop optimization, and/or possibly suboptimal floating
point instruction sequences. Given that Paul Khuong is working on
using SSE2 for complex arithmetic, it will be interesting to see what
kind of effect that has on performance.&lt;/p&gt;

&lt;p&gt;I did not bother implementing complexes as user-defined objects --
depending on how you view this benchmark it either invalidates my
numbers, or focuses on the only real point there is...&lt;/p&gt;

&lt;p&gt;Conclusions?&lt;/p&gt;

&lt;p&gt;While not hitting the C++ target today, I think these numbers
support SBCL's call to fame as a high-performance Common Lisp
compiler.&lt;/p&gt;

&lt;p&gt;Also, an important reminder for any CL advocates: when comparing
the speed of a Common Lisp implementation like SBCL to C or C++,
&lt;i&gt;never&lt;/i&gt; say Common Lisp is faster -- not even in those cases when
it is. Everything most performance oriented people know conflicts with
that, so that even if you are right, they will not believe
you. Instead, say something like: &lt;i&gt;"Even for low level number
crunching SBCL can generate code that approaches gcc or g++ in
speed."&lt;/i&gt;, or whatever the point you are trying to make is. Say
&lt;i&gt;almost as fast&lt;/i&gt;, not faster -- and please, don't lie. Nothing is
worse PR then unfounded claims.&lt;/p&gt;

&lt;p&gt;As a bonus, some interesting -- and related -- papers from &lt;a
href="http://www.lrde.epita.fr/~didier/about/news.php"&gt;Didier
Verna&lt;/a&gt; "On Behaviour and Performance of Common Lisp": &lt;a
href="http://www.lrde.epita.fr/~didier/research/verna.06.ecoop.pdf"&gt;Beating
C in Scientific Computing Applications&lt;/a&gt;, and &lt;a
href="http://www.lrde.epita.fr/~didier/research/verna.09.ilc.pdf"&gt;CLOS
Efficiency: Instantiation&lt;/a&gt;.&lt;/p&gt;
  </description>
  </item>
<item>
  <title>ELS 2009</title>
   <category>hacking</category>
   <link>http://random-state.net/log/3452867927.html</link>
   <pubDate>Mon, 1 Jun 2009 20:58:47 +0300</pubDate>
   <description>
&lt;p&gt;Milan was hot, and the campus quite confusing -- but the symposium
itself was very good.&lt;/p&gt;

&lt;p&gt;Given that ELS 2008 netted ~50 registrants, the 45 who showed up
this time seem a clear success to me, given both the ILC earlier this
year and the general state of the econony the world over.&lt;/p&gt;

&lt;p&gt;Talks and papers: mostly quite interesting! Particular highlights
for me personally were Thomas Burdick's paper on compiling FEXPRs, and
Pascal Costanza's on a hygiene compatible macro system for Common
Lisp.&lt;/p&gt;

&lt;p&gt;About the latter: I'm fairly sure that gensyms could be used for
aliases instead of interned symbols, since in case of locals the
externalization does the right thing, and for global names one can use
&lt;tt&gt;(SYMBOL-VALUE 'FOO)&lt;/tt&gt; etc as aliases. Moreover, it appears to
me that it would not be particularly hard for the compiler to provide
aliases implicitly -- making a hygienic macro system that integrates
nicely with vanilla CL a relatively simple matter. Cool stuff.&lt;/p&gt;

&lt;p&gt;On an unrelated note, I think many people who were around for the
ANSI standardization process have a distinctly different view of
Common Lisp than those who came in later: the first group of people
have a tendency to see it as a historical accident were they didn't
get some things right -- whereas I (and I believe many others too) see
CL as something that &lt;i&gt;did&lt;/i&gt; get many things right. These aren't
mutually exclusive of course, but is a different emphasis.&lt;p&gt;
  </description>
  </item>
<item>
  <title>DEFGLOBAL in SBCL</title>
   <category>hacking</category>
   <link>http://random-state.net/log/3451988257.html</link>
   <pubDate>Fri, 22 May 2009 16:37:37 +0300</pubDate>
   <description>
&lt;p&gt;I recently added support for global variables in SBCL: they cannot
be rebound or made unbound, which are occasionally useful semantic properties.&lt;/p&gt;

&lt;p&gt;More importantly, however, they are an efficiency measure for those
cases when a threaded application is using a special as global
variable -- never rebinding it: on threaded builds special variable
lookup has a fair bit of overhead: in addition to normal boundness
checking the system also needs to check for the thread-local
binding. Using a global instead allows just grabbing the value slot of
the symbol:&lt;/p&gt;

&lt;pre&gt;(defparameter *foo* 0)
(defparameter *foo2* 0)

(defun foo (n)
  (declare (fixnum n))
  (dotimes (i n)
    (setf *foo* *foo2*)
    (setf *foo2* *foo*)))

(defglobal **bar** 0)
(defglobal **bar2** 0)

(defun bar (n)
  (declare (fixnum n))
  (dotimes (i n)
    (setf **bar** **bar2**)
    (setf **bar2** **bar**)))

(time (foo 100000000))
(time (bar 100000000))&lt;/pre&gt;

&lt;p&gt;FOO takes 0.55 seconds of run time, and BAR 0.37 -- about 30%
difference in favor of global variables.&lt;/p&gt;

&lt;p&gt;It needs to be taken into account, however, that this is an
&lt;i&gt;extremely&lt;/i&gt; artificial benchmark. Eg. doing bignum arithmetic in
the loop loses the difference between specials and globals into noise,
so gains for real applications are likely to be much smaller -- and
almost certainly nonexistent for a large class of applications.&lt;/p&gt;

&lt;p&gt;Secondary effects due to reduced code size are possible,
however. This is what assignment from &lt;tt&gt;*FOO2*&lt;/tt&gt; to &lt;tt&gt;*FOO*&lt;/tt&gt;
(both special variables) looks like:&lt;/p&gt;

&lt;pre&gt;;      1E2: L0:   8B05A8419E11     MOV EAX, [#x119E41A8]      ; '*FOO2*
;      1E8:       8B5011           MOV EDX, [EAX+17]
;      1EB:       64               FS-SEGMENT-PREFIX
;      1EC:       8B12             MOV EDX, [EDX]
;      1EE:       83FA5A           CMP EDX, 90
;      1F1:       7503             JNE L1
;      1F3:       8B50FD           MOV EDX, [EAX-3]
;      1F6: L1:   83FA4A           CMP EDX, 74
;      1F9:       7464             JEQ L8
;      1FB:       8B35AC419E11     MOV ESI, [#x119E41AC]      ; '*FOO*
;      201:       8B4611           MOV EAX, [ESI+17]
;      204:       64               FS-SEGMENT-PREFIX
;      205:       83385A           CMP DWORD PTR [EAX], 90
;      208:       7405             JEQ L2
;      20A:       64               FS-SEGMENT-PREFIX
;      20B:       8910             MOV [EAX], EDX
;      20D:       EB03             JMP L3
;      20F: L2:   8956FD           MOV [ESI-3], EDX&lt;/pre&gt;

&lt;p&gt;Contrast and compare with assigment from &lt;tt&gt;**BAR2**&lt;/tt&gt; to &lt;tt&gt;**BAR**&lt;/tt&gt; (both globals):&lt;/p&gt;

&lt;pre&gt;;      A18: L0:   8B15CC69A211     MOV EDX, [#x11A269CC]      ; '**BAR2**
;      A1E:       8B52FD           MOV EDX, [EDX-3]
;      A21:       8B1DC869A211     MOV EBX, [#x11A269C8]      ; '**BAR**
;      A27:       8953FD           MOV [EBX-3], EDX&lt;/pre&gt;

&lt;p&gt;Hopefully there are users out there who find this of use! To me at
least they seems like a natural match for locks, for example.&lt;/p&gt;
  </description>
  </item>
<item>
  <title>Array Improvements</title>
   <category>hacking</category>
   <link>http://random-state.net/log/3451622139.html</link>
   <pubDate>Mon, 18 May 2009 10:55:39 +0300</pubDate>
   <description>
&lt;p&gt;I've just about completed a slew of array related optimizations in
SBCL. Since the details are not all that interesting, I'll focus
on couple of my favorite changes:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;MAKE-ARRAY&lt;/b&gt; already had some compiler transforms that
were able to take care of some aspects of it, but there were some IMO
perfectly idiomatic cases that were dog slow:&lt;/p&gt;

&lt;pre&gt;;; the compiler didn't realize it could elide the call to LIST and use
;; it's arguments directly to initialize the array -- ditto for VECTOR
;; and backquoted forms in place of LIST.
(defun bar (x y z)
  (make-array 3 :initial-contents (list x y z)))&lt;/pre&gt;

&lt;p&gt;Previously this resulted in consing up the list at runtime, and
then making a full call to &lt;tt&gt;MAKE-ARRAY&lt;/tt&gt;, including keyword
argument parsing and everything. I'll spare you the disassembly --
pick up an pre 1.0.28.51 SBCL and see for yourself if you must.&lt;/p&gt;

&lt;p&gt;Now, we are instead able to transform the above into something
like this:&lt;/p&gt;

&lt;pre&gt;(lambda (x y z)
  (initialize-vector (allocate-vector ...) x y z))&lt;/pre&gt;

&lt;p&gt;..which in turn is open coded, resulting in an almost 90% speedup.
If you were aware of this deficiency, and used explicit &lt;tt&gt;(SETF
AREF)&lt;/tt&gt; to initialize the array, you were manually doing what the
compiler now does automatically -- and will not see any performance
improvements.&lt;/p&gt;

&lt;p&gt;What's more, now we are also able to stack allocate arrays in
the presence of &lt;tt&gt;:INITIAL-CONTENTS&lt;/tt&gt; or &lt;tt&gt;:INITIAL-ELEMENT&lt;/tt&gt;,
including those allocated with a call to &lt;tt&gt;VECTOR&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;FILL&lt;/b&gt; also now benefits from a better transform.
If the array element type is known (and fills a bunch of criteria),
we are able to fill much more efficiently by using "bit bashing".
The implementation functions for this have existed in SBCL for quite
a while now, thanks to Nathan Froyd, but were not used until now.&lt;/p&gt;

&lt;p&gt;Consider eg. an array with element type &lt;tt&gt;(UNSIGNED-BYTE 8)&lt;/tt&gt;.
By first filling a word with 4 (8 on 64 bit platforms) copies of the
initial element, we can fill the array a word at a time -- poor man's
SIMD, if you will. This strategy was already used for filling bit
vectors, but now it applies to all types where it is safe.&lt;/p&gt;

&lt;p&gt;Upshot: upto 90% faster &lt;tt&gt;FILL&lt;/tt&gt;.&lt;/p&gt;
  </description>
  </item>
<item>
  <title>New lisp book by Barski available for preorder</title>
   <category>hacking</category>
   <link>http://random-state.net/log/3450081424.html</link>
   <pubDate>Thu, 30 Apr 2009 14:57:04 +0300</pubDate>
   <description>
&lt;p&gt;I'm not sure if this is the "new O'Reilly lisp book" that some have
been hinting at, but coming later this year is &lt;a
href="http://oreilly.com/catalog/9781593272005/"&gt;Land of Lisp, Learn
to Program in Lisp, One Game at a Time!&lt;/a&gt; by Conrad Barski. I'm
guessing the O'Reilly book is something different, as this has "No
Starch Press" as the publisher, unless that's a subsidiary of O'Reilly
or something.&lt;/p&gt;
  </description>
  </item>
  </channel>
  </rss>
