追記

忙しくてほったらかし.
ACLではデフォルトでcompileされてなくて,明示的に(compile 'fib)しないといけないということに気づきました.
Allegroから枝分かれしたAMCLがデフォルトでコンパイルされるようになっていたので,勝手にそう思いこんでいたようです.

CL-USER(3): (time (fib 30))
; cpu time (non-gc) 30 msec user, 0 msec system
; cpu time (gc)     0 msec user, 0 msec system
; cpu time (total)  30 msec user, 0 msec system
; real time  27 msec
; space allocation:
;  1 cons cell, 0 other bytes, 0 static bytes
1346269
CL-USER(4): (time (fib 40))
; cpu time (non-gc) 3,310 msec user, 0 msec system
; cpu time (gc)     0 msec user, 0 msec system
; cpu time (total)  3,310 msec user, 0 msec system
; real time  3,315 msec
; space allocation:
;  1 cons cell, 0 other bytes, 0 static bytes
165580141

CL-USER(8): (time (ack 3 7))
; cpu time (non-gc) 0 msec user, 0 msec system
; cpu time (gc)     0 msec user, 0 msec system
; cpu time (total)  0 msec user, 0 msec system
; real time  4 msec
; space allocation:
;  2 cons cells, 0 other bytes, 0 static bytes
1021
CL-USER(9): (time (ack 3 9))
; cpu time (non-gc) 60 msec user, 0 msec system
; cpu time (gc)     0 msec user, 0 msec system
; cpu time (total)  60 msec user, 0 msec system
; real time  61 msec
; space allocation:
;  2 cons cells, 0 other bytes, 0 static bytes
4093

というわけでsbclを上回る結果が得られました.
有償ソフトの面目躍如でした.

CommonLISP実装を比較する

単純な計算を比較してCommonLISP実装を比較してみる.
とはいってもCommonLISPにはいろいろコンパイルオプションがあるので,単純に比較するのはできないのだけど,あくまで参考程度ということで..
比較したのは以下のフィボナッシ数列とアッカーマン関数再帰関数である.
#リスト処理もやっていない関数で比較にならないって?あくまで参考程度だから..

(defun fib (x)
  (cond *1 (fib (- x 2)))))
)

(defun ack (M N)
  (cond *2
        *3
        (t
         (ack (- M 1) (ack M (- N 1)))))
  )

マシンはMacPro(2x2.66G Dual-Core Intel Xeon,メモリー1G).

  • AllegroCommonLISP 8.0

Optimization settings: safety 1, space 1, speed 1, debug 2
です.

CL-USER(8): (time (fib 30))
; cpu time (non-gc) 10,920 msec user, 20 msec system
; cpu time (gc)     4,880 msec user, 30 msec system
; cpu time (total)  15,800 msec user, 50 msec system
; real time  15,854 msec
; space allocation:
;  66,284,964 cons cells, -934,298,656 other bytes, 0 static bytes
1346269

CL-USER(10): (time (ack 3 7))
; cpu time (non-gc) 3,230 msec user, 30 msec system
; cpu time (gc)     14,580 msec user, 0 msec system
; cpu time (total)  17,810 msec user, 30 msec system
; real time  17,844 msec
; space allocation:
;  22,900,810 cons cells, 893,934,112 other bytes, 39,488 static bytes
1021

(fib 30)が約15秒
(ack 3 7)が約17秒
コンパイルオプションを結構いじらないといけないんでしょうか..

 * (time (fib 30))

Evaluation took:
  0.058 seconds of real time
  0.057549 seconds of user run time
  9.e-5 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  8,192 bytes consed.
1346269

 * (time (fib 40))

Evaluation took:
  7.516 seconds of real time
  7.515032 seconds of user run time
  0.001482 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  0 bytes consed.
165580141

 * (time (ack 3 7))

Evaluation took:
  0.012 seconds of real time
  0.011678 seconds of user run time
  5.5e-5 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  0 bytes consed.
1021

 * (time (ack 3 9))

Evaluation took:
  0.189 seconds of real time
  0.188628 seconds of user run time
  1.76e-4 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  0 bytes consed.
4093


(fib 30)は0.058秒,(fib 40)は7.5秒
(ack 3 7)は0.012秒,(ack 3 9)は0.189秒

結果としては,デフォルト値ではsbclの圧勝ということになりますが,コンパイルオプションの調整でどうなりますでしょうか..

*1:= x 0) 1) ((= x 1) 1) (t (+ (fib (- x 1

*2:= M 0) (+ N 1

*3:= N 0) (ack (- M 1) 1

CommonLISPからOpenGLを動かす.

動かすのはもちろん,X11から.「ターミナル」から動かすとsbclごと落ちるので注意.

$ sbcl   
This is SBCL 1.0.2, an implementation of ANSI Common Lisp.
More information about SBCL is available at http://www.sbcl.org/.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
 * (require :asdf)

("ASDF")
 * (asdf:oos 'asdf:load-op :cl-glut-examples)
............(メッセージがいっぱい出てくる)............
NIL

読み込み完了.あとは実行するのみ

 * (cl-glut-examples:gears)
26397 frames in 5.0 seconds = 5279.400 FPS
26636 frames in 5.0 seconds = 5327.200 FPS
26666 frames in 5.0 seconds = 5333.200 FPS
26683 frames in 5.0 seconds = 5336.600 FPS
26531 frames in 5.0 seconds = 5306.200 FPS

という具合.ポリゴン数が少ないせいか,ちょっと信じられない数値ではあるが..

スクリーンショットがうまくとれないほど,高速で回転している?

さらにrun-examplesでどこかでみたことがあるようなデモをみることができる.

 * (cl-glut-examples:run-examples)

OpenGLUTをコンパイル&インストール

Esden氏のBLOGにあるようにOpenGLUTをダウンロードしてコンパイルする.
このとき,最近のMacだとX11 SDKがインストールされていないとうまくコンパイルできない模様.DeveloperやX11を入れても入らないみたいなので注意.MacOSXインストールディスクのXcode Tools/Packagesフォルダの中にパッケージとしてある.
OpenGLUTのコンパイルは展開したフォルダに移動し,configure,make, make installする.

$ CPPFLAGS="-I/usr/X11R6/include" ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... no
checking for mawk... no
checking for nawk... no
.............(省略).................


$ make
make  all-recursive
Making all in src
if /bin/sh ../libtool --mode=compile --tag=CC gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include  -I/usr/X11R6/include  -w -MT libopenglut_la-og_callbacks.lo -MD -MP -MF ".deps/libopenglut_la-og_callbacks.Tpo" -c -o libopenglut_la-og_callbacks.lo `test -f 'og_callbacks.c' || echo './'`og_callbacks.c; \
then mv -f ".deps/libopenglut_la-og_callbacks.Tpo" ".deps/libopenglut_la-og_callbacks.Plo"; else rm -f ".deps/libopenglut_la-og_callbacks.Tpo"; exit 1; fi
.............(省略).................


$ sudo make install
Password:
Making install in src
test -z "/usr/local/lib" || /bin/sh ../mkinstalldirs "/usr/local/lib"
 /bin/sh ../libtool --mode=install /usr/bin/install -c  'libopenglut.la' '/usr/local/lib/libopenglut.la'
/usr/bin/install -c .libs/libopenglut.1.0.0.dylib /usr/local/lib/libopenglut.1.0.0.dylib
(cd /usr/local/lib && rm -f libopenglut.1.dylib && ln -s libopenglut.1.0.0.dylib libopenglut.1.dylib)
(cd /usr/local/lib && rm -f libopenglut.dylib && ln -s libopenglut.1.0.0.dylib libopenglut.dylib)
/usr/bin/install -c .libs/libopenglut.lai /usr/local/lib/libopenglut.la
/usr/bin/install -c .libs/libopenglut.a /usr/local/lib/libopenglut.a
.............(省略).................

しかし,このままでは,ライブラリの名前がlibopenglut.dylibなので,シンボリックリンクを作成する.

$ cd /usr/local/lib
$ ls
charset.alias           libopenglut.1.dylib     libopenglut.dylib       sbcl
libopenglut.1.0.0.dylib libopenglut.a           libopenglut.la
$ sudo ln -s libopenglut.1.0.0.dylib libglut.dylib
Password:

これで完了.

cl-openglパッケージを登録

darcsでダウンロードしたフォルダをsbclに登録する.

  1. フォルダ全体を/usr/local/lib/sbcl/site/に移動.
$ mv ~/cl-opengl/ /usr/local/lib/sbcl/site/ 
  1. cl-opengl/*.asdファイルからsite-systemsフォルダ内にシンボリックリンクを作成
$ cd /usr/local/lib/sbcl/site-systems
$ ln -s ../site/cl-opengl/*.asd .

これで完了.

  1. あとはasdfでロードできる.
 * (require :asdf)

("ASDF")
 * (asdf:oos 'asdf:load-op :cffi)

; loading system definition from /usr/local/lib/sbcl/site-systems/cffi.asd into
; #
; registering # as CFFI
NIL
 * (asdf:oos 'asdf:load-op :cl-opengl)

; loading system definition from /usr/local/lib/sbcl/site-systems/cl-opengl.asd
; into #
; registering # as CL-OPENGL
; compiling file "/usr/local/lib/sbcl/site/cl-opengl/gl/package.lisp" (written 05 MAR 2007 04:17:57 PM):
; compiling (DEFPACKAGE #:CL-OPENGL ...)
...........(省略)...........

※最初にロードしたときはコンパイルが実行される.
しかし,glutについては,ライブラリをインストールしていないので,以下のようにエラーが出力される.

 * (asdf:oos 'asdf:load-op :cl-glut-examples)

; loading system definition from
; /usr/local/lib/sbcl/site-systems/cl-glut-examples.asd into #
; registering # as CL-GLUT-EXAMPLES
; loading system definition from /usr/local/lib/sbcl/site-systems/cl-glut.asd
; into #
; registering # as CL-GLUT
; loading system definition from /usr/local/lib/sbcl/site-systems/cl-opengl.asd
; into #
; registering # as CL-OPENGL
; loading system definition from /usr/local/lib/sbcl/site-systems/cffi.asd into
; #
; registering # as CFFI
; loading system definition from /usr/local/lib/sbcl/site-systems/cl-glu.asd
; into #
; registering # as CL-GLU
; compiling file "/usr/local/lib/sbcl/site/cl-opengl/glut/package.lisp" (written 05 MAR 2007 04:17:57 PM):
; compiling (IN-PACKAGE #:CL-USER)
; compiling (DEFPACKAGE #:CL-GLUT ...)

; /usr/local/lib/sbcl/site/cl-opengl/glut/package.fasl written
; compilation finished in 0:00:00
; compiling file "/usr/local/lib/sbcl/site/cl-opengl/glut/library.lisp" (written 05 MAR 2007 04:17:57 PM):
; compiling (IN-PACKAGE :CL-GLUT)
; compiling (DEFINE-FOREIGN-LIBRARY GLUT ...)
; compiling (USE-FOREIGN-LIBRARY GLUT)

; /usr/local/lib/sbcl/site/cl-opengl/glut/library.fasl written
; compilation finished in 0:00:00

debugger invoked on a LOAD-FOREIGN-LIBRARY-ERROR:
  Unable to load any of the alternatives:
   ("libglut.dylib" "libglut.3.dylib")

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [RETRY    ] Try loading the foreign library again.
  1: [USE-VALUE] Use another library instead.
  2: [RETRY    ] Retry performing # on
                 #.
  3: [ACCEPT   ] Continue, treating # on
                 # as having been
                 successful.
  4: [ABORT    ] Exit debugger, returning to top level.

(NIL
 (:OR "libglut.dylib" "libglut.3.dylib")
 "Unable to load any of the alternatives:~%   ~S")
0] 

OpenGLUTをインストールする必要がある.

darcsをインストール

パッケージcl-openglをインストールするには,darcsという,aptみたいな,パッケージマネージャを使う必要がある.パッケージマネージャがいろいろありすぎて大変だと思いつつ,これをサイトからダウンロードしてインストールする.Mac用はdarcsのオフィシャルサイトからdmg形式でダウンロードしてインストールできる.
インストール後,
Esden氏のBLOGに書いてあるとおり,以下のコマンドを実行するだけでダウンロードは完了する.

$ darcs get http://www.common-lisp.net/project/cl-opengl/darcs/cl-opengl/
Copying patch 46 of 46... done!
Applying patch 46 of 46... done.
Finished getting.

これでファイル群はダウンロードが完了する.
Proxy内部からやるときは,以下のように,環境変数を指定すればよい.

$ export http_proxy=":"
$ export DARCS_PROXYUSERPWD=":"

ASDF-installを使ってCFFIをインストール

さてさて,OpenGLをフリーのCommonLispから使いたい..というわけでググったところ,cl-openglが使える模様であるので,これをインストールしたいわけである.このcl-openglは,CFFIという外部関数を呼ぶ出すパッケージから使うことができるみたい.さらにこのCFFIは,これはASDFのパッケージとなっているみたい.
ASDFというのは,CommonLispにおけるライブラリを管理するシステムでPerlCPANのようにインターネットからダウンロードする仕掛けASDF-installが用意されている(MCLに依存しまくりのmuは恥ずかしながら,今頃知ったというわけなのであるが).
このあたりのやり方はEsden氏のBLOGにあったので,これを参考にしている.
SBCLでは,ASDFASDF-installはプレインストールされているので,requireするだけである.
※ここでProxyで守られた内部ネットワークだとうまくいかなかった.

  1. sbclを起動
  2. asdf-installをロード
 * (require 'asdf-install)

; loading system definition from
; /usr/local/lib/sbcl/sb-bsd-sockets/sb-bsd-sockets.asd into #
; registering # as SB-BSD-SOCKETS
; registering # as SB-BSD-SOCKETS-TESTS
; loading system definition from /usr/local/lib/sbcl/sb-posix/sb-posix.asd into
; #
; registering # as SB-POSIX
; registering # as SB-POSIX-TESTS
("ASDF-INSTALL" "SB-BSD-SOCKETS" "SB-POSIX" "SB-GROVEL" "ASDF")
  1. CFFIをネットワークからインストール

最初にシステムワイドにインストールするか,個人環境にインストールするかを聞いてくる.
システムワイドに登録したければ,1を選ぶが,権限がないとエラーで止まる.
その後,GPGでシグニチャをチェックするか聞いてくるが,SKIP-GPG-CHECKを選んで,ここでは無視した.
いくつか関連するパッケージをインストールするためか,何度か,同じことを聞かれて,同じように答えれば完了する.

 * (asdf-install:install :cffi)
Install where?
1) System-wide install:
System in /usr/local/lib/sbcl/site-systems/
Files in /usr/local/lib/sbcl/site/
2) Personal installation:
System in /Users/username/.sbcl/systems/
Files in /Users/username/.sbcl/site/
    • > 1
Downloading 153995 bytes from http://common-lisp.net/project/cffi/releases/cffi_0.9.2.tar.gz ... debugger invoked on a ASDF-INSTALL::KEY-NOT-FOUND: No key found for key id 0xF1DCE557E86007A0. Try some command like gpg --recv-keys 0xF1DCE557E86007A0 Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [SKIP-GPG-CHECK] Don't check GPG signature for this package 1: [ABORT ] Exit debugger, returning to top level. (ASDF-INSTALL::VERIFY-GPG-SIGNATURE/STRING "-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (Darwin) iD8DBQBFAdkO8dzlV+hgB6ARAmzTAJ9C/oHh1+ECAmcZJBnWKYtrWLe13ACfQcpA g2x4HitUK9F0jqk1CAcbhFU= =NpH4 -----END PGP SIGNATURE----- " #P"/Users/username/CFFI.asdf-install-tmp") 0] :0 Installing /Users/username/CFFI.asdf-install-tmp in /usr/local/lib/sbcl/site/,/usr/local/lib/sbcl/site-systems/ cffi_0.9.2/ ............(省略).............