親子丼(2)

葡萄はすっかり収穫が終わってもう実は無いはずなんだけど、何故か数房だけが忘れ去られたように ぶら下がっていた。道路に面したフェンスの外に房が出ていたので、面倒くさくなって収穫 するのを止めたのだろうか?

道路に実を出してるって事は、公共な人が収穫しても良いって事だよね。道路が通学路にも なっているんで、公共の餓鬼共の目に触れないはずは無いんだけど、いつ前を通ってもそのまま になっている。道路に落ちている物を無闇に拾って食べてはいけませんって、きつく指導されて るのかな? それとも、寒くなって貴腐葡萄になるまで待ってから、おやつにするのだろうか? 興味は尽きない。

今朝前を通りかかったら、ぶどうの樹にわらが巻いてあった。冬篭もりの準備が着々と進んで います。来年も良い実を付けてねって労わりだな。樹と言うか蔓をじっと見ていて気が付いた んだけど、所々にテープでマーキングがしてある。これなんだろう? 今年はこの部分に実を 付けてくれましたよって事なのかなあ? 一度葡萄畑の人に聞いてみたいものだ。

冬篭もりと言えば、干し柿作りがさかんに行われています。干し柿暖簾が、そこかしこの軒下 にぶら下がってます。年が明ける頃になると、真っ白に粉を噴いて美味しくなるんだよな。

渋柿は、干し柿にするのが常だけど、焼酎だかと一緒に保管しておくと、渋が抜けるとか 聞いた事があるな。実験してみるかな。 まあ、もう少しすれば、実家で甘い柿が取れるようになるんで、それを待てばいいかな。

実家にある柿ノ木、甥が柿を食べて、その種を庭に植えたら、大きな樹になったというから、 もう20年にはなる樹だな。今年も元気一杯に実を付けている。今から楽しみだ。

csi csc chicken

先週は、親子丼って事で、鶏と玉子達をやったんだけど、まあそれは委員会LispのASDFで楽を しましょうって事だった。鶏を入れると、csi、csc、chickenが入るんだけど、それぞれは何者よ? ちょいとmanしてみた。

       csi - The CHICKEN Scheme interpreter
       csc - driver program for the CHICKEN Scheme compiler
       chicken - A Scheme-to-C translator

これって、京都発のKCLと同じ思想で 作られたものなのね。以下、上記ページから引用します。

KCl(GCL)は色々とすぐれているのですが、その中でも、もっとも特徴的ですぐれている点は、
そのほとんどがC言語で書かれている。
それに加えて、Lispコンパイラの生成するオブジェクト・コードがC言語のソースとなって
いる点です。
CommonLispを作り、移植性を持たせるのは、大変なことです。
しかも、性能を良くするのは非常に大変なことです。
移植性があり、性能のよいコンパイラを作るのも非常に難しいことです。
KClはオブジェクト・コードを C言語とすることで、いとも簡単にその壁を乗り越えています。
実は、当時は筆者は「Cのソースを出すなんて単なる手抜きか?」と思っていたのですが…
その後、SparcやMipsを始めとするRISCの時代になり、C言語コンパイラの最適化が非常に
良くなり、へたなコンパイラではどうしようもない時代になります。 

頑張らない生き方 なんて本を最近読みましたが、真髄はしんどかったら無理しないで、他人に 投げちゃえって事で、一脈通じる所が有りますね。また、unixの思想にも合致してる。 何から何まで抱え込んじゃった、Windowsの有名アプリはBugも抱え込んじゃって、苦し紛れに それは仕様ですと言い続けている。KCLとかchickenは、そういう世界とは無縁だな。

頑張らない生き方を標榜する人は多くて、ここを見るRSchemeとか ikarus等もそうみたいです。逆に頑張りすぎて、Schemeを こよなく愛してる人達をいらいらせているもいますけどね。 (R7RSで、ゆり戻しはあるのだろうかと、ボソッと独り言)

お手並み拝見

インタープリタを使って、ああでもないこーでもないと実験90%、コード書き10%するんだな。 んでもって、虫が居ないと思われるタイミングで、コンパイルするとな。なんだ、ルビーで おいらがコード書く時と同じじゃん。irbで実験して、良かったら、コードを貼り付けると。 いにしえの昔からそうして来たけど、最近はそれにユニットテストなんてのが加わっているのね。

コンパイラの威力確認は、フィボだな。

(define (fib n)
  (if (<= n 1)
      1
      (+ (fib (- n 1)) (fib (- n 2)))))

(define (meas n)
  (time (fib n)))

GCがどれぐらいの頻度で行われているか、調べてみる。

#;1> ; loading /home/sakae/chi/fib.scm ...
#;2> (set-gc-report! #t)
#;3> (meas 25)
  :
[GC] level  1   gcs(minor)  219 gcs(major)  15
[GC] stack      0xbfbdea50      0xbfbde934      0xbfbfea50
[GC]  from      0x2870a000      0x28723ddc      0x28747090      0x00019ddc
[GC]    to      0x28748000      0x28748000      0x28785090
[GC] 0 locatives (from 32)
[GC] level  1   gcs(minor)  219 gcs(major)  16
[GC] stack      0xbfbdea50      0xbfbde964      0xbfbfea50
[GC]  from      0x28748000      0x28761dc4      0x28785090      0x00019dc4
[GC]    to      0x2870a000      0x2870a000      0x28747090
[GC] 0 locatives (from 32)
0.154s CPU time, 0.006s GC time (major), 10 mutations, 16/3617 GCs (major/minor\
)
121393
#;6> (meas 38)
80.351s CPU time, 4.288s GC time (major), 10 mutations, 8622/1884013 GCs (major\
/minor)
63245986

インタープリタだと80秒。

[sakae@cdr ~/chi]$ csc fib.scm
[sakae@cdr ~/chi]$ ./fib
8.18s CPU time, 0.066s GC time (major), 175/183194 GCs (major/minor)

コンパイルすると8秒だから、10倍早くなったのね。ちなみに、goshだと

gosh> (meas 38)
;(time (fib n))
; real  10.851
; user  10.703
; sys    0.000
63245986

gaucheの人は、頑張る人なんだなあ。

で、上記では、さっとコンパイルして実行形式が出来ちゃったけど、そのあたりは どうなってるの?

丸投げの現場

cscはコンパイラードライバーって説明だけど、gccみたいな物だな。すると、gccのオプション風に きっとなってるんだろうな。あたりを付けて、

[sakae@cdr ~/chi]$ csc -v fib.scm
/usr/local/bin/chicken fib.scm -output-file fib.c
gcc fib.c -o fib.o -c  -fno-strict-aliasing -fwrapv -DHAVE_CHICKEN_CONFIG_H -DC_ENABLE_PTABLES -O2 -pipe -fno-strict-aliasing -I"/usr/local/include/chicken"
rm fib.c
gcc fib.o -o fib -L"/usr/local/lib"  -Wl,-R"/usr/local/lib" -lchicken -lm -lpthread
rm fib.o

ははは、ビンゴ! 舞台裏が丸見えだ。chickenで *.scm を、Cのソースに変換してんのね。 どんなコードになるか確認してみっか。

[sakae@cdr ~/chi]$ chicken fib.scm -output-file fib.c
[sakae@cdr ~/chi]$ wc fib.c
     345     863   11161 fib.c
[sakae@cdr ~/chi]$ indent fib.c fib-indent.c

整形しても、読む気がしないよ。変な所で頑張らない事にする。

[sakae@cdr ~/chi]$ file fib
fib: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 8.0 (800107), not stripped
[sakae@cdr ~/chi]$ ldd fib
fib:
        libchicken.so.6 => /usr/local/lib/libchicken.so.6 (0x2808f000)
        libm.so.5 => /lib/libm.so.5 (0x284de000)
        libthr.so.3 => /lib/libthr.so.3 (0x284f8000)
        libc.so.7 => /lib/libc.so.7 (0x2850d000)
[sakae@cdr ~/chi]$ ls -l fib
-rwxr-xr-x  1 sakae  kuma  12755 11 10 12:25 fib*
[sakae@cdr ~/chi]$ strip fib
[sakae@cdr ~/chi]$ ls -l fib
-rwxr-xr-x  1 sakae  kuma  9532 11 10 12:48 fib*

で、ちょっと余分にキーを叩いて、スピードアップ出来ないか、bit頑張ってみる。

[sakae@cdr ~/chi]$ csc -vv -O5 fib.scm
/usr/local/bin/chicken fib.scm -output-file fib.c -verbose -optimize-level 5
Loading compiler extensions...
debugging info: none
loading identifier database /usr/local/lib/chicken/6/modules.db ...
compiling `fib.scm' ...
pass: source
pass: canonicalized
pass: initial node tree
pass: cps
pass: analysis
pass: optimized-iteration
pass: analysis
pass: optimized-iteration
pass: analysis
pass: optimized-iteration
pass: analysis
pass: optimized-iteration
pass: analysis
pass: optimized-iteration
pass: analysis
pass: optimized-iteration
pass: analysis
pass: optimized-iteration
pass: analysis
pass: optimized
pass: final-analysis
pass: closure-converted
pass: unboxing
generating `fib.c' ...
compilation finished.
gcc fib.c -o fib.o -c  -fno-strict-aliasing -fwrapv -DHAVE_CHICKEN_CONFIG_H -DC_ENABLE_PTABLES -O2 -pipe -fno-strict-aliasing -O3 -fomit-frame-pointer -I"/usr/local/include/chicken"
rm fib.c
gcc fib.o -o fib -L"/usr/local/lib"  -Wl,-R"/usr/local/lib" -lchicken -lm -lpthread
rm fib.o
[sakae@cdr ~/chi]$ ./fib
5.632s CPU time, 0.159s GC time (major), 142/146588 GCs (major/minor)

ちょっとだけ早くなったな。もっといろいろなオプションを試すと、爆速になるかな。 ああ、オプションを -vvv にすると、gccが下請けを呼び出す状況も見られて面白い。

それから、fib.cを作る過程で、ごちゃごちゃやってるのと同じのをどこかで見たな、えっと どこだったけかな? 「MinCaml」のコンパイラ

clojureとか委員会Lispでフィボ

折角なので、上記で出てきたfibをclojureと、sbclでやってみます。

user> (clojure-version)
"1.3.0"
user> (time (fib 38))
"Elapsed time: 22644.159 msecs"
CL-USER> (time (fib 38))
Evaluation took:
  2.592 seconds of real time
  2.578699 seconds of total run time (2.575512 user, 0.003187 system)
  99.50% CPU
  5,690,094,803 processor cycles
  0 bytes consed

63245986

sbcl速いな。

特異日

今日は11月11日でチーズの日らしい。11月1日はワンワンワンで犬の日だったらしい。全く、売らんが がための匂いがプンプンしていますなあ。

おいらなら、今日は100年に一度の特異日として認定しちゃうぞ。

日本式にyymmddでも、ヨーロッパ式にddmmyyでも、アメリカ式にmmddyyでも、皆同じ日を表す。 date.rbのあの苦労はなんだ。どんなにへぼなコードを書いたって、今日だけは全て同じ年月日に認定される。

プログラマの平安の日だ。だから、記念して、ちょっと早く更新してみた。