Gauche:VMの最適化:JIT

Gauche:VMの最適化:JIT

昔のやつ:


(Shiro:2023/12/27 09:15:12 UTC)

JITというか、一部をネイティブコードにする実験をやってたんだけど、現行のVM+ネイティブコードをSUBRとして呼び出し、では結局ほとんどこれ以上速くならない、という結論に。

最大の問題は、途中にネイティブコード呼び出しが挟まっても継続がうまく動くようにすることで、現在はネイティブコード呼び出しをトランポリンにすることで実現している。つまり、ネイティブコードから他のSchemeルーチンを呼ぶ場合、

ここで、(3)の箇所で継続が捕捉される可能性があるわけだが、再開に必要な情報は全部VMスタックに入っているのでいくらでも再起動できるとうわけ。

しかしこれだと、Scheme関数呼び出しの度にネイティブコードでの関数のエピローグとプロローグが余計に呼ばれることになる。普通のSchemeプログラムでは関数呼び出しは非常に頻繁で、本体が数インストラクションなのにVMスタック操作とプロローグ/エピローグがごそっとついたsubrをたくさん呼び出すことになって、結局速度が上がらない。

アイディアとしては、

  1. 現行のVMは残すが、subrからの関数呼び出しについては、継続に関する情報をpushするだけで呼び出し自体はCPUのcall/retでやる。継続の呼び出しが無ければネイティブの関数呼び出し/リターンと同じ。継続が呼ばれた場合はlongjmpでCスタックを破棄し、VMにセーブされてた情報から残りの部分を実行する。
  2. 現在のVMを捨てて総とっかえ

Last modified : 2023/12/27 09:21:54 UTC