Feature #6289
closedメソッドのインライン化について
Description
Rubyはメソッド呼び出しが重いです。
一方でC++などはmov数個とcall一個で終わりますね?
そこでインライン化を考えてみようと思ったのですが、C++と違って動的なクラス定義が許されている言語なので安易にインライン化はできません。
安全にインライン化するためには
インライン化できるメソッドの条件
・インライン化されるメソッドはクラス定義、メソッド定義を呼ばない
・インライン化できるメソッドしか呼ばない
四則演算や配列操作は明らかにクラス定義、メソッド定義を呼ばないので、インライン化できます。
するとそれらのみを使うメソッドはインライン化できます。
こうしてボトムアップでインライン化できるかどうかを全てのメソッドに対して決めることができます。
ここでついでにそのメソッドから呼ばれる可能性のあるメソッドを列挙してリストにしておきます。
次の問題はインライン化されたあとにその内部で呼ばれるメソッド定義が書き換わった場合に、インライン化をやり直さないといけないのですが
これは先ほど作ったメソッドのリストを見て、定義が書き換わったかどうかを判定できます。
分かりやすく言えば、"メソッドの飛び先のチェックがループの外に出たら速い"ってことです¶
四則演算とか、オーバーライドされる可能性のせいで遅くなるのはもったいなあと。99.9999%のケースでオーバーライドされないんだから・・・
99.9999%側なのか0.00001%側なのかのチェックをループの外に出すのって最適化の基本かなと
bignumへの移行を考えると、add jcc sub jcc みたいにコンディショナルジャンプを一個ごとに挟まないといけなそうですが
分岐予測テーブルを汚染しそう
実際の実装はLLVMでやってみようかな¶
最近Ruby開発に興味が出たひよっこですが。こんなことやってみようかなと、とりあえずつぶやいてみます
もしかしてRuby1.9で既にやられてるのかな?ISEQとか怪しい
Updated by ko1 (Koichi Sasada) about 13 years ago
- Status changed from Open to Closed
Feature request は決意表明の場とは違うので,とりあえず閉じます.
頑張って下さい.
ちなみに,Rubinius という実装が LLVM で JIT compiler を実装しており,inline 化もやっていると思います.
以下,コメントです.
- 「インライン化できるメソッドの条件」は間違い
- 「四則演算や配列操作は明らかにクラス定義、メソッド定義を呼ばないので、インライン化できます」は間違い(厳密には説明が面倒なので略)
- 「これは先ほど作ったメソッドのリストを見て、定義が書き換わったかどうかを判定できます」そう思います.
- 「チェックをループの外に出すのって最適化の基本かなと」そう思います.
- 「分岐予測テーブルを汚染しそう」そう思わなくもないですが,他で散々汚しているし,最近の CPU は BTB もでかいし.
- 「もしかしてRuby1.9で既にやられてるのかな」やっていません.
あとは,on stack replacement (JVM のほうで資料が豊富)とか,inline 化の戦略(一般的なコンパイラの文献で色々あります)とか,調べてみると良いと思います.
Ruby だと,Proc(と eval,binding)があるので,環境について考えるのが面倒だったりします.
参考になれば幸いです.