mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-15 09:56:24 -04:00
* doc/*: Revert to Docbook 4.1 DOCTYPE for compatibility with older systems such as Debian Woody. Add catalog for Darwin's fink and for partially for Redhat. Need to add OS detection for fink in Makefile and stylesheet location for RedHat in catalog-redhat.xml
140 lines
6.8 KiB
XML
140 lines
6.8 KiB
XML
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.1/docbookx.dtd" [
|
|
<!ENTITY % myents SYSTEM "entities.inc">
|
|
%myents;
|
|
]>
|
|
|
|
<chapter id="efficiency"><title>Efficiency</title>
|
|
|
|
<para>FIXME: The material in the &CMUCL; manual about getting good
|
|
performance from the compiler should be reviewed, reformatted in
|
|
DocBook, lightly edited for &SBCL;, and substituted into this
|
|
manual. In the meantime, the original &CMUCL; manual is still 95+%
|
|
correct for the &SBCL; version of the &Python; compiler. See the
|
|
sections
|
|
<itemizedlist>
|
|
<listitem><para>Advanced Compiler Use and Efficiency Hints</para></listitem>
|
|
<listitem><para>Advanced Compiler Introduction</para></listitem>
|
|
<listitem><para>More About Types in Python</para></listitem>
|
|
<listitem><para>Type Inference</para></listitem>
|
|
<listitem><para>Source Optimization</para></listitem>
|
|
<listitem><para>Tail Recursion</para></listitem>
|
|
<listitem><para>Local Call</para></listitem>
|
|
<listitem><para>Block Compilation</para></listitem>
|
|
<listitem><para>Inline Expansion</para></listitem>
|
|
<listitem><para>Object Representation</para></listitem>
|
|
<listitem><para>Numbers</para></listitem>
|
|
<listitem><para>General Efficiency Hints</para></listitem>
|
|
<listitem><para>Efficiency Notes</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>Besides this information from the &CMUCL; manual, there are a
|
|
few other points to keep in mind.
|
|
<itemizedlist>
|
|
<listitem><para>The &CMUCL; manual doesn't seem to state it explicitly,
|
|
but &Python; has a mental block about type inference when
|
|
assignment is involved. &Python; is very aggressive and clever
|
|
about inferring the types of values bound with <function>let</function>,
|
|
<function>let*</function>, inline function call, and so forth. However,
|
|
it's much more passive and dumb about inferring the types of
|
|
values assigned with <function>setq</function>, <function>setf</function>, and
|
|
friends. It would be nice to fix this, but in the meantime don't
|
|
expect that just because it's very smart about types in most
|
|
respects it will be smart about types involved in assignments.
|
|
(This doesn't affect its ability to benefit from explicit type
|
|
declarations involving the assigned variables, only its ability to
|
|
get by without explicit type declarations.)</para></listitem>
|
|
<!-- FIXME: Python dislikes assignments, but not in type
|
|
inference. The real problems are loop induction, closed over
|
|
variables and aliases. -->
|
|
<listitem><para>Since the time the &CMUCL; manual was written,
|
|
&CMUCL; (and thus &SBCL;) has gotten a generational garbage
|
|
collector. This means that there are some efficiency implications
|
|
of various patterns of memory usage which aren't discussed in the
|
|
&CMUCL; manual. (Some new material should be written about
|
|
this.)</para></listitem>
|
|
<listitem><para>&SBCL; has some important known efficiency problems.
|
|
Perhaps the most important are
|
|
<itemizedlist>
|
|
<listitem><para>There is no support for the &ANSI;
|
|
<parameter>dynamic-extent</parameter> declaration, not even for
|
|
closures or <parameter>&rest</parameter> lists.</para></listitem>
|
|
<listitem><para>The garbage collector is not particularly
|
|
efficient.</para></listitem>
|
|
<listitem><para>Various aspects of the PCL implementation
|
|
of CLOS are more inefficient than necessary.</para></listitem>
|
|
</itemizedlist>
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>Finally, note that &CommonLisp; defines many constructs which, in
|
|
the infamous phrase, <quote>could be compiled efficiently by a
|
|
sufficiently smart compiler</quote>. The phrase is infamous because
|
|
making a compiler which actually is sufficiently smart to find all
|
|
these optimizations systematically is well beyond the state of the art
|
|
of current compiler technology. Instead, they're optimized on a
|
|
case-by-case basis by hand-written code, or not optimized at all if
|
|
the appropriate case hasn't been hand-coded. Some cases where no such
|
|
hand-coding has been done as of &SBCL; version 0.6.3 include
|
|
<itemizedlist>
|
|
<listitem><para><literal>(reduce #'f x)</literal>
|
|
where the type of <varname>x</varname> is known at compile
|
|
time</para></listitem>
|
|
<listitem><para>various bit vector operations, e.g.
|
|
<literal>(position 0 some-bit-vector)</literal></para></listitem>
|
|
</itemizedlist>
|
|
If your system's performance is suffering because of some construct
|
|
which could in principle be compiled efficiently, but which the &SBCL;
|
|
compiler can't in practice compile efficiently, consider writing a
|
|
patch to the compiler and submitting it for inclusion in the main
|
|
sources. Such code is often reasonably straightforward to write;
|
|
search the sources for the string <quote><function>deftransform</function></quote>
|
|
to find many examples (some straightforward, some less so).</para>
|
|
|
|
<sect1 id="modular-arithmetic"><title>Modular arithmetic</title>
|
|
<para>
|
|
Some numeric functions have a property: <varname>N</varname> lower bits of
|
|
the result depend only on <varname>N</varname> lower bits of (all or some)
|
|
arguments. If the compiler sees an expression of form <literal>(logand
|
|
exp mask)</literal>, where <varname>exp</varname> is a tree of such "good" functions
|
|
and <varname>mask</varname> is known to be of type <type>(unsigned-byte
|
|
w)</type>, where <varname>w</varname> is a "good" width, all intermediate results
|
|
will be cut to <varname>w</varname> bits (but it is not done for variables
|
|
and constants!). This often results in an ability to use simple
|
|
machine instructions for the functions.
|
|
</para>
|
|
|
|
<para>
|
|
Consider an example.
|
|
<programlisting>
|
|
(defun i (x y)
|
|
(declare (type (unsigned-byte 32) x y))
|
|
(ldb (byte 32 0) (logxor x (lognot y))))
|
|
</programlisting>
|
|
The result of <literal>(lognot y)</literal> will be negative and of
|
|
type <type>(signed-byte 33)</type>, so a naive implementation on a 32-bit
|
|
platform is unable to use 32-bit arithmetic here. But modular
|
|
arithmetic optimizer is able to do it: because the result is cut down
|
|
to 32 bits, the compiler will replace <function>logxor</function>
|
|
and <function>lognot</function> with versions cutting results to 32 bits, and
|
|
because terminals (here---expressions <literal>x</literal> and <literal>y</literal>)
|
|
are also of type <type>(unsigned-byte 32)</type>, 32-bit machine
|
|
arithmetic can be used.
|
|
</para>
|
|
|
|
<note><para> As of &SBCL; 0.8.5 "good" functions
|
|
are <function>+</function>, <function>-</function>; <function>logand</function>, <function>logior</function>,
|
|
<function>logxor</function>, <function>lognot</function> and their combinations;
|
|
and <function>ash</function> with the positive second argument. "Good" widths
|
|
are 32 on HPPA, MIPS, PPC, Sparc and X86 and 64 on Alpha. While it is
|
|
possible to support smaller widths as well, currently it is not
|
|
implemented.
|
|
</para></note>
|
|
|
|
</sect1>
|
|
|
|
</chapter>
|