Linuxはじめました & エスケープ解析の検討
この間思い立ってLinux(Debian)をインストールしました。yarv2llvmを動かしてみたら動きませんでした。ごちゃごちゃ調べてみたら、次のようにするととりあえず動きます。わざわざ付いているのを削るので多分問題があるんでしょうが。
llvm/lib/Target/X86/X86JITInfo.cpp
// Check if building with -fPIC #if defined(__PIC__) && __PIC__ && defined(__linux__) - #define ASMCALLSUFFIX "@PLT" + #define ASMCALLSUFFIX #else #define ASMCALLSUFFIX #endif
早速、aoベンチを試してみました、Cygwin: 2分20秒 → Linux: 1分50秒くらいでした。もうちょっと速くしたいと思い、配列のアクセスをインライン化するとかごちゃごちゃ試しているのですがあまり効果がないです。
やはり、オブジェクトのアロケーションを減らすところに手をいれないといけないなと思い、オブジェクトのスタック割付を検討します。
スタック割付を行うにあたって問題は2つあります。
- 割り付けた後、オブジェクトをどう組み立てるか
- エスケープ解析
このうち、オブジェクトをどう組み立てるかはクラスごとにRubyのソースから初期化手順をコピーしてくるしかないかなと思います。難しいところは無いのですが、Rubyのバージョンアップに上手についていける仕組みが欲しいところです。
エスケープ解析は難しそうです。単純にグローバル変数、インスタンス変数に書き込まれた、戻り値になったものはエスケープするとすれば簡単ですが、それだとaoベンチでは効果が少ないかなと思います。
例えば、こんな感じのプログラムの場合、fooもbarもエスケープしないと判断して、スタックに割り付けるようにしたいところです。
class TestClass def initialize(a) @a = a end end def escape_test foo = Array.new foo[1] = 1 bar = TestClass.new(foo) nil end
エスケープ解析は型推論の一環で行う予定なのですが、オブジェクトの寿命に関するデータ間の関係(リンク)を管理する必要があるなと思います。例えば、上の例では、fooがエスケープするかはbarがエスケープするかに掛かっているとかそんな感じです。
既に実現している同じ型というリンクだけでも大変なのに、同じようなリンクを加えて管理しないといけないとなると大変そうです。