とりあえず方針として、
- Xbyakを使ってC側で実装する。
- コンパイル中に見つかったクロージャーもコンパイルして呼び出しは可能な限りネイティブにする。(これの恩恵はでかい、実装がかなり楽)
- 他の手続き呼び出し用引数フレームはVMのスタックを使う。
まぁ、気になるのはパフォーマンスだろう。以下のコードでベンチマークを取ってみた。
(add-load-path "sitelib")
(add-load-path "lib")
(import (sagittarius vm) (time))
(define (fib n)
(if (<= n 2)
1
(+ (fib (- n 1)) (fib (- n 2)))))
(print "vm")
(time (fib 35))
(newline)
(jit-compile-closure! fib)
(print "native")
(time (fib 35))
(newline)
(define (tak x y z)
(if (not (< y x))
z
(tak (tak (- x 1) y z)
(tak (- y 1) z x)
(tak (- z 1) x y))))
(define (run-tak count)
(do ((i 0 (+ i 1))
(r (tak 18 12 6) (tak 18 12 6)))
((= i count) r)))
(define count 200)
(print "vm")
(time (run-tak count))
(newline)
(jit-compile-closure! run-tak)
(print "native")
(time (run-tak count))
(newline)
JITという割りに、VMは現状では勝手にコンパイルしないので手動でコンパイル。テストだけならこの方が便利。っで、結果は以下(CoreDuo 1.6Ghz, Cygwin on Windows XP)$ ./build/sash.exe test.scm vm ;; (fib 35) ;; 3.093750 real 2.797000 user 0.000000 sys native ;; (fib 35) ;; 1.875000 real 1.859000 user 0.000000 sys vm ;; (run-tak count) ;; 2.015625 real 1.875000 user 0.000000 sys native ;; (run-tak count) ;; 1.312500 real 1.187000 user 0.000000 sys速くはなっているんだけど、驚くほどということも無く。なんか、頑張ればVMとコンパイラの最適化で叩きだせるんじゃね?というくらいの速度改善なのがなんとも悲しい。問答無用で5倍くらい速くなるならやる気も格段に違うんだけど・・・
ベンチマークのコードを多少修正。(Gambitベンチのと同じ回数まわすようにした)
No comments:
Post a Comment