Gnu Common Lisp(GCL)/Kyoto Common Lisp(KCL)の最適化について

たけおか@AXE (竹岡尚三)

Common Lispは、実用言語である。
なので、Common Lispの最適化がすごい例を、ちょっと書いてみたり。

GCLは、もともとのKCLを強化して、AKCL (Austin KCL)となり、それを維持強化しているもの。

(GCLのページの歴史にもそれは書いてある http://www.gnu.org/software/gcl/ )

下に示す最適化は、KCLの時代からまったく同じで、強力だった。



素朴に書くと、下のような階乗のプログラム…

(defun fa2 (x y)
  (if(zerop x)  y
    (fa2 (1- x) (* y x))))

型をきちんと指定して、関数の返す型や、途中の変数が保持するデータが、
fixnum(小さな整数,実現によるが大体28bit〜30bitぐらい?)であると、
処理系に教える、と、下のようになる。

(defun fa3 (x y)
  (declare (fixnum x y))
  (if(zerop x) (the fixnum y)
    (fa3 (the fixnum(1- x)) (the fixnum(* y x)))))
 
これをコンパイルする。
※実際には、
(disassemble 'fa3)
を実行する。


  :
;; Note: Tail-recursive call of FA3 was replaced by iteration.
  :
OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3
  :
/* function definition for FA3 */

static void L1()
{
       :
    {long V1;
    long V2;
       :
TTL:;
    if(!((V1)==0)){
    goto T2;}
    base[2]= CMPmake_fixnum(V2);
    vs_top=(vs_base=base+2)+1;
    return;
    goto T2;
T2:;
    {long V3;
    V3= (long)(V1)-1;
    V2= (long)(V2)*(V1);
    V1= V3;}
    goto TTL;
    }
}
 
となる。

ということで、TTL - goto TTL;の単純なループとなり、
ループの中の演算は、longの
乗算, マイナス1, 0との比較
という整数演算のみになっている。

ちなみに、機械語は
  30: 85 d2                 test   %edx,%edx
  32: 74 06                 je     3a <_L1+0x3a>
  34: 0f af ca              imul   %edx,%ecx
  37: 4a                    dec    %edx
  38: eb f6                 jmp    30 <_L1+0x30>
 
となっている。
(いまどきのCコンパイラなら、V3という変数はなくなって当然)


ちなみに、GCL/KCLは、コンパイルのオプションは、デフォールトで
OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3
速度優先、実行時エラーチェック無し
となる。今回もそのまま。


今回使用したのは、
GCL (GNU Common Lisp) 2.6.6 CLtL1 Feb 10 2005 08:19:54
OSはWindowsXP




蛇足)
GCL/KCLは、Lispソースからコンパイルした、オブジェクトはC言語である。
なので、コンパイル結果を見るのが、非常に楽である。
また、GCL/KCLは、disassembleすると、こっそりとソースを再コンパイルしてそれを表示する。
GCLの基本的なアーキテクチャはKCLからほとんど変わっていない。


僕の自慢は、
このKCLの最適化を、1986年ごろ(「KCLが凄いぞ!」と世界中で有名になっていたころ)に、
KCLの作者の一人である萩谷さんに、KABAでじきじきに教えてもらったこと
である。


たけおかの Lispページ 目次

GnuEmacsと、Gnu Common Lispを一緒に使うと便利! こちら。

CommonLispで記述した、StarTrek(1976年頃流行した古いゲーム)


Prologの入門文書に飽きた人に

Prologで記述した、StarTrek(1976年頃流行した古いゲーム)


たけおか(竹岡尚三)のホームページ