Lisp日記 2012-02-19 — #:g1

Posted 2012-02-20 13:34:00 GMT

一週間ぶりな感じなのであまり日記という感じでもなくなりつつあり。

分かったこと

疑問は増えていくがちゃんと調べてないので特に解決したことは無し。
serious-conditionの直下のクラスってなんだったけなという時には、やっぱりLispWorksのようなクラスブラウザが便利。clim-listenerのやつでも良いけど。

分からないこと/調べること

srfi-35を移植しようとしているが、condition関係ってmopの外だったろうか。できないことはなさそうだけど、無名コンディションも作れない気がするし、スロットをmop的にいじっても実装依存が激しい気がした。

やりたいこと

mopを使わない場合と、使った場合の実際のコードの比較があると学習のためには良いかなと思ったりした。自分の場合問題意識を共有できないと全然覚えられない。mop関係の場合、解決策だけ提示されている場合が多い気がしていて、一体これはなんに使うのかと宙ぶらりんになることが多いので、対照例によって具体的な不便さが分かれば覚えるのには都合が良い。
CCL 1.8にcaseマクロの最適化が付くらしいので、どういう実装になっているか調べてみたい。
Lucid CLにはそういう機能があったらしい。たまたま(3.4.4 CASE macro optimization)というのを3ヶ月位前にみつけて自分なりに色々考えて遊んでいた。
自分的には、gcc拡張のラベルアドレスみたいな感じで、テーブルを使って一発分岐なのかなと思ったりしたけれど、実際どうなんだろう。CCL 1.8もどのレベルで最適化しているのだろうか。caseからアセンブリまで一発なのか、アセンブリレベルで色々変形した後なのか。case以外のことも考えると、後者の方がメリットがありそう。
こんな感じのを、処理系依存のアセンブリを書く機能で書いてみて測定してみたいなと思ってたけど、自分には難しいので放置。
; nasm -f elf64 case.s
; ld -s -o case case.o

bits 64
section .text
global _start

_start: mov rcx, 1 ;アイテム=番号 lea rax, [item2-item1] ;ジャンプ命令の幅 mul rcx ;番号*幅 => 飛ぶ距離 lea rdx, [item1+rax] ;飛び先の番地 jmp rdx item1: lea rdx, [a] jmp rdx item2: lea rdx, [b] jmp rdx lea rdx, [c] jmp rdx lea rdx, [d] jmp rdx a: ;; exit 0 mov rax, 60 ; sys_exit mov rdi, 0 syscall b: ;; exit 0 mov rax, 60 ; sys_exit mov rdi, 1 syscall c: ;; exit 0 mov rax, 60 ; sys_exit mov rdi, 2 syscall d: ;; exit 0 mov rax, 60 ; sys_exit mov rdi, 3 syscall

lispのレベルで考えると、クロージャーを配列に詰めて、呼び出しても大体似たような事ができる。関数呼び出しのコストが、caseでの分岐より少ない場合には良いのかもしれない。
これをマクロにして解決かと思ったけど、クロージャーにして配列に詰めるとマクロが設置された周辺の変数環境の捕捉が難しくなるので、caseよりずっと使い勝手が悪い気がした(caseの関数版みたいなことになる)
また、caseのマクロも全部の節で比較しているから遅くなるのであって順番を変更したり途中を適当にジャンプしたりできることが確定できるなら、マクロのレベルでも最適化できてしまうんじゃないかとも思った。
結局のところCLでVMでも書いて分岐が深刻な問題になったりする場合は別として、普通のアプリのレベルではそんなに効いて来ることはなさそうなので、ちょっとした別の工夫で引っくり返してしまうことが可能な気がした。

みつけたもの

Lisp in Small Piecesが5250円。この本の割には安いかなと思った。

思ったこと

Schemeのオリジナルの一連の論文を眺めてみようかなと思ったり。 ■

comments powered by Disqus