アセンブリコードを読んでみたら - Scheme VM を書く
Gaku さんに指摘された件。
命令列の終端に達しているか?を毎回チェックしているが重そうだよねえという話。
確かに僕も気になっていた。これを番人形式にすれば速いのではなかろうか。
ただやってみるのではなくてアセンブリのコードを眺める。
その後にどれくらい改善されるかを予想するのが良さそうということに。
movl 12(%ebp), %eax movl 16(%eax), %eax cmpl -120(%ebp), %eax jb .L948
うん。まあ予想通りのコード。
番人形式にするならば他のインストラクションと同じ道をたどり dispatch_table を使った jump になる。
goto *dispatch_table[(*pc_++).val()];
leal -1452(%ebp), %eax movl %eax, (%esp) call _ZNK6scheme6Object3valEv movl _ZZN6scheme2VM3runENS_6ObjectEE14dispatch_table(,%eax,4), %eax movl %eax, -1472(%ebp) jmp .L1887 .L952: .L1887: jmp *-1472(%ebp)
ええええええ。 val() がインライン展開されてねぇ。毎回 call されている。
word val() const { return val_; }
public にして (*pc_++).val で参照するようにした。
この結果には満足していますが偶然たどり着いたようなもの(&Gakuさんのおかげ)なのでちと修行します。
まだ速くなりそう。
これくらいインライン展開されるだろうと思ってたんだけど。
クリティカルなところはちゃんと見ないとな。