PUSH 命令やスタック参照を速く出来ないかと考えたところスタックポインタを本当にポインタにすることを思いつきました。
今までは VM が Gauche 「でも」書かれていることを考慮してスタックポインタ sp は stack 配列の index として機能していました。
つまり n 番目の要素へのアクセスは stack[n] で、スタックへの push は stack[sp++] = obj となります。
しかしながら C++ の世界だけを考えれば sp は Object へのポインタであれば良いはずです。
例えばよく行われる push は *sp++ = obj; と書け stack 変数の参照は必要ないです。
PUSH 命令の中で変数への参照が 1 つ減るので大きな効果がありそうだと予想しています。
実装してみました。
benchmark | sec |
---|---|
./bench/fib.scm | 0.090 |
./bench/case.scm | 0.405 |
./bench/let.scm | 0.083 |
./bench/tak.scm | 0.061 |
./bench/decode.scm | 0.030 |
数字では分かりづらいので mumurik さんのブログにもあったとおり目標値を赤線で示したグラフで見てみましょう。
目標である赤い線を下回れば目標を達成したことになります。
以下のように fib, case では大きな速度向上が見られました。(ちなみに tak は現時点で目標である Gauche より速くなっています。)
let は微妙ですね。なぜこういう動きになるのかまだ調べていません。
グラフを描くってのは良いです。
目標到達のためにどの程度の改善が必要か目で見て分かるようになります。
さらに施した改善が目標到達にどの程度寄与したかも分かります。
実装や考察にかかった時間も分かっていますから、結果がかけたコストに見合うかなども判断する材料になります。
今回施したスタックポインタの改善と同じくらいのインパクトのある改善をあと2回くらい実施すれば目標に到達できそうです。
さてグラフには既にプロットされていますが、スタックポインタと同様にプログラムカウンタもポインタにすれば同じくらいの速度改善が期待できるのではないのでしょうか。
やってみたところ速くなりました。