SlideShare uma empresa Scribd logo
1 de 19
Baixar para ler offline
mrubyのJIT
三浦英樹
(miura1729)
自己紹介
ここから南に行った知多半島の武豊町で水道
屋をやっています
仕事の合間にmrubynのJITコンパイラをこそこ
そ作っています。作る理由はストレス解消って
感じです
mrubyのJITとは
mrubyにパッチを当ててJITコンパイルをおこなうようにしたものです
コード生成にXbyakを使わせてもらっています。
(使いやすくて安定していてお勧め)
基本的に32bitのCygwinで開発しているのでそれが一番安心です。
一応、32bitのLinuxでもそこそこ動きますし、64bitのLinuxでもちょっと
動きます
オリジナルのmrubyの1~10倍くらいの速度だと思います。CRubyと比
べると速かったり遅かったりです。だいたい、4倍くらいでしょうか。
mruby流れ
構文解析
コード生成
バイトコードインタプリタ
AST
RITE バイトコード列
構文解析
コード生成
バイトコードインタプリタ
AST
RITE バイトコード列
mruby流れ
主にこの部分に
手を入れる
バイトコード列の例
irep 0x20160790 nregs=11 nlocals=4 pools=3 syms=5 reps=1
file: benchmark/bm_fib.rb
14 000 OP_ENTER 2:0:0:0:0:0:0
15 001 OP_LOADSELF R4
15 002 OP_STRING R5 L(0) ; ""
15 003 OP_GETCONST R6 :Irep
15 004 OP_MOVE R7 R1 ; R1:ele
15 005 OP_GETUPVAR R8 1 0
15 006 OP_SEND R6 :disasm 2
15 007 OP_STRCAT R5 R6
15 008 OP_STRING R6 L(2) ; " n"
15 009 OP_STRCAT R5 R6
15 010 OP_SEND R4 :print 1
16 011 OP_GETUPVAR R4 1 0
16 012 OP_MOVE R5 R2 ; R2:i
16 013 OP_SEND R4 :reg_type 1
16 014 OP_LAMBDA R5 I(+1) 2
16 015 OP_SENDB R4 :each 0
16 016 OP_RETURN R4 normal
バイトコードインタプリタの構成
命令のフェッチ
MOVE
命令の実行命令の実行命令の実行命令の実行
SEND ADD LOADI CALL
素朴な考え
命令のフェッチ
MOVE
命令の実行命令の実行命令の実行命令の実行
SEND ADD LOADI CALL
この部分の実行した機械語をどこかに覚えておい
て再実行すれば速くなるんじゃね?
こんな感じ
命令のフェッチ
MOVE
命令の実行命令の実行命令の実行命令の実行
SEND ADD LOADI CALL
MOVE
命令の生成命令の生成命令の生成命令の生成
SEND ADD LOADI CALL
既に生成された命令があれば
それを実行
実行できないなら
インタプリタのループに戻る
生成された機械語
実行
機械語
書き込み
ループはいつか終わる(普通は)
これだけではうまくいかない
引数に整数かと思ったら文字列がやってきた
ポリモーフィズムとか
そこでガードを導入する
実行の前提条件をチェックする、仕組み
 ・ やっていることはただのif文
(機械語だから条件判定と条件ブランチ)
 
 ・ 前提条件の例
    レジスタに入っているデータ型
    レジスタに入っているクラス
レジスタの値 
(→ if文とかループもこれを使う)
・ 前提が当てはまらなかったらVMに戻る
   VMの状態を設定する必要がある (面倒)
mrubyのVMの状態の例
mrb->c      VMのコンテクスト(Fiberとかを使わない限り変化しない)
mrb->c->ci    メソッドの呼び出し履歴
proc 現在実行中のブロック/メソッドのProcオブジェクト
irep 現在実行中のメソッド/ブロックのプログラムコードと
          その付加情報(定数とかシンボルテーブルとか)
pc 現在実行中の命令
syms シンボルテーブル
pool 定数テーブル
mrb->c->stack レジスタ(昔はregsという変数があったが今は無い)
VMに戻るときはこの辺の変数を正しく設定する必要がある
 常に整合を保つのではなく、VMに戻るときというのがミソ
メソッド呼び出し・戻りとVMに戻る直前が主な更新ポイント
LuaJITだとVMをアセンブラで書いて状態を変更しやすくしている
Tracing JITのまとめ
(メソッドレベルのJITと比べて)
いい所
  いつでもVMに戻れるから実装の面倒な部分をVMに丸投げできる。
実装が面倒な機能満載のRubyにはありがたい特徴
  開発初期の段階からすべてのRubyプログラムが動くのでモチベー
ションが高い
悪い所
 いつでもVMに戻れるようにいろいろ変数を設定する必要があるか
ら遅い。
 CとかLLVMを生成しようとすると何かと困難
なんとか速くする
なにも工夫しないTracing JITはやっぱり遅い
  多分、オリジナルのインタプリタの方が速い
そこで、なんとか速くする工夫をしないといけない
  工夫のしどころはいろいろある 
    (なにせLuaJIT、PypyはTracing JITだし)
速くする方針はだいたいこんな所
  ・ ガードを無くす
  ・ 余計なメモリアクセスを無くす
  ・ メソッド呼び出しを無くす
ガードを無くす
単純な例
OP_LOADI R3, 1
OP_ADD R2, 1, :+
OP_ADDでR3がFIXNUMであるかのチェックはいらない
レジスタの型を覚えておき、確定するならガードを生成しない
→ これは既に実装済み
もっと複雑なものは簡単にはいかないので静的に型推論を行う必要が
あると思われる
→ これはまだ(興味がある人は後で話しましょう)
余計なメモリアクセスを減らす
単純な例
OP_LOADI R3, 1
OP_ADD R2, 1, :+
R3は1であることをコンパイル時に覚えておき(コードは生成しない)、
ADD命令生成時にR3は1である情報を利用して即値を使う機械語を生
成する
→ これは既に実装済み
もっと複雑なものはレジスタ割り当て(たとえばLiner Scan Register
Allocation)を利用する必要があるでしょう。
→ これはまだ(興味がある人は後で話しましょう)
メソッド呼び出しを無くす
mrubyのメソッド呼び出しはとにかく重い。
Tracing JITだからコンパイルしても同じことをしないといけない
  → じゃあ軽くしようと思うけどすごく困難
     例外とかバックトレースとか考えると仕方が無い
そこで、メソッド呼び出しを無くす(インライン化する)というアプローチが有効
   インライン化にも2つの方針がある
    ・ C言語で実装されたメソッドをmrubyのメソッド呼び出し
  のプロトコルを無視して呼び出す
      → 例外が発生しないことが前提
         簡単ですごく効果がある(数割速くなるとかざら)
・ mrubyで書かれたメソッドをインライン化する
      → これはまだ実装していない
         すごく大変。(興味がある人は後で話しましょう)
面倒くさいRubyの機能
 ・ メソッドの再定義 (make testで使いまくり)
 ・ Fiber (h2oで使いまくり)
 ・ send (optcarrot(ファミコンエミュレータ)で使いまくり)
 ・ Procオブジェクト
 ・ eval (require代わりに使ったりするから無視するわけにはいかない)
だいたい自己書き換えコードかVMに丸投げで解決
あと、Cで実装されたメソッドでtarget_classをnullにするとcontextを更新出来る機能がとて
も役に立っている(すごく込み入った話なので省略)
おしまい
ありがとうございました

Mais conteúdo relacionado

Mais procurados

mrubyでETロボコンに出よう
mrubyでETロボコンに出ようmrubyでETロボコンに出よう
mrubyでETロボコンに出ようyamanekko
 
すごいぞVuetify!! 〜ポートフォリオを作ってみた〜
すごいぞVuetify!! 〜ポートフォリオを作ってみた〜すごいぞVuetify!! 〜ポートフォリオを作ってみた〜
すごいぞVuetify!! 〜ポートフォリオを作ってみた〜SHOYAYAMAMOTO
 
mruby を C# に 組み込んでみる
mruby を C# に 組み込んでみるmruby を C# に 組み込んでみる
mruby を C# に 組み込んでみるRyosuke Akiyama
 
RubyGemsで公開されているライブラリをモンキーパッチした話
RubyGemsで公開されているライブラリをモンキーパッチした話RubyGemsで公開されているライブラリをモンキーパッチした話
RubyGemsで公開されているライブラリをモンキーパッチした話SHOYAYAMAMOTO
 
Veri2048
Veri2048Veri2048
Veri2048ga sin
 
サーバ擬人化ユーザ会Lt資料 qpstudy lite
サーバ擬人化ユーザ会Lt資料 qpstudy liteサーバ擬人化ユーザ会Lt資料 qpstudy lite
サーバ擬人化ユーザ会Lt資料 qpstudy liteSeiichiro Ishida
 
Ltdd01gulp入門公開用資料
Ltdd01gulp入門公開用資料Ltdd01gulp入門公開用資料
Ltdd01gulp入門公開用資料Kazuya Matsubara
 
zshでコマンドライン履歴を活用する
zshでコマンドライン履歴を活用するzshでコマンドライン履歴を活用する
zshでコマンドライン履歴を活用するHideaki Miyake
 
エディタこだわってますか?
エディタこだわってますか?エディタこだわってますか?
エディタこだわってますか?Tetsuya Chiba
 
本格的に始めるzsh
本格的に始めるzsh本格的に始めるzsh
本格的に始めるzshHideaki Miyake
 
ペパボ福岡支社におけるRubyの活用事例
ペパボ福岡支社におけるRubyの活用事例ペパボ福岡支社におけるRubyの活用事例
ペパボ福岡支社におけるRubyの活用事例Uchio Kondo
 
Php beginnerが beginner + になるための話
Php beginnerが beginner + になるための話Php beginnerが beginner + になるための話
Php beginnerが beginner + になるための話yuichi kishimoto
 
chibi:bitとMicroPythonで始めるフィジカルコンピューティング
chibi:bitとMicroPythonで始めるフィジカルコンピューティングchibi:bitとMicroPythonで始めるフィジカルコンピューティング
chibi:bitとMicroPythonで始めるフィジカルコンピューティングMinoru Inachi
 
ゴルフゲームでUnityの限界を突破する方法
ゴルフゲームでUnityの限界を突破する方法ゴルフゲームでUnityの限界を突破する方法
ゴルフゲームでUnityの限界を突破する方法Nohina Hidenari
 
組込み向けスクリプト言語mrubyをEV3で動かしてみよう
組込み向けスクリプト言語mrubyをEV3で動かしてみよう組込み向けスクリプト言語mrubyをEV3で動かしてみよう
組込み向けスクリプト言語mrubyをEV3で動かしてみようTakuya Azumi
 
はじめませんか? Bash on Windows
はじめませんか? Bash on Windowsはじめませんか? Bash on Windows
はじめませんか? Bash on WindowsHideaki Aoyagi
 
クラウドサービス、AWS/Azure/GCP それぞれの Text to Speechを比べてみた
クラウドサービス、AWS/Azure/GCP それぞれの Text to Speechを比べてみたクラウドサービス、AWS/Azure/GCP それぞれの Text to Speechを比べてみた
クラウドサービス、AWS/Azure/GCP それぞれの Text to Speechを比べてみたDaizen Ikehara
 

Mais procurados (20)

mrubyでETロボコンに出よう
mrubyでETロボコンに出ようmrubyでETロボコンに出よう
mrubyでETロボコンに出よう
 
すごいぞVuetify!! 〜ポートフォリオを作ってみた〜
すごいぞVuetify!! 〜ポートフォリオを作ってみた〜すごいぞVuetify!! 〜ポートフォリオを作ってみた〜
すごいぞVuetify!! 〜ポートフォリオを作ってみた〜
 
mruby を C# に 組み込んでみる
mruby を C# に 組み込んでみるmruby を C# に 組み込んでみる
mruby を C# に 組み込んでみる
 
RubyGemsで公開されているライブラリをモンキーパッチした話
RubyGemsで公開されているライブラリをモンキーパッチした話RubyGemsで公開されているライブラリをモンキーパッチした話
RubyGemsで公開されているライブラリをモンキーパッチした話
 
Veri2048
Veri2048Veri2048
Veri2048
 
サーバ擬人化ユーザ会Lt資料 qpstudy lite
サーバ擬人化ユーザ会Lt資料 qpstudy liteサーバ擬人化ユーザ会Lt資料 qpstudy lite
サーバ擬人化ユーザ会Lt資料 qpstudy lite
 
Memcache Queue
Memcache QueueMemcache Queue
Memcache Queue
 
Ltdd01gulp入門公開用資料
Ltdd01gulp入門公開用資料Ltdd01gulp入門公開用資料
Ltdd01gulp入門公開用資料
 
Git Boot Camp for Designer
Git Boot Camp for DesignerGit Boot Camp for Designer
Git Boot Camp for Designer
 
zshでコマンドライン履歴を活用する
zshでコマンドライン履歴を活用するzshでコマンドライン履歴を活用する
zshでコマンドライン履歴を活用する
 
エディタこだわってますか?
エディタこだわってますか?エディタこだわってますか?
エディタこだわってますか?
 
本格的に始めるzsh
本格的に始めるzsh本格的に始めるzsh
本格的に始めるzsh
 
ペパボ福岡支社におけるRubyの活用事例
ペパボ福岡支社におけるRubyの活用事例ペパボ福岡支社におけるRubyの活用事例
ペパボ福岡支社におけるRubyの活用事例
 
Php beginnerが beginner + になるための話
Php beginnerが beginner + になるための話Php beginnerが beginner + になるための話
Php beginnerが beginner + になるための話
 
chibi:bitとMicroPythonで始めるフィジカルコンピューティング
chibi:bitとMicroPythonで始めるフィジカルコンピューティングchibi:bitとMicroPythonで始めるフィジカルコンピューティング
chibi:bitとMicroPythonで始めるフィジカルコンピューティング
 
ゴルフゲームでUnityの限界を突破する方法
ゴルフゲームでUnityの限界を突破する方法ゴルフゲームでUnityの限界を突破する方法
ゴルフゲームでUnityの限界を突破する方法
 
組込み向けスクリプト言語mrubyをEV3で動かしてみよう
組込み向けスクリプト言語mrubyをEV3で動かしてみよう組込み向けスクリプト言語mrubyをEV3で動かしてみよう
組込み向けスクリプト言語mrubyをEV3で動かしてみよう
 
はじめませんか? Bash on Windows
はじめませんか? Bash on Windowsはじめませんか? Bash on Windows
はじめませんか? Bash on Windows
 
クラウドサービス、AWS/Azure/GCP それぞれの Text to Speechを比べてみた
クラウドサービス、AWS/Azure/GCP それぞれの Text to Speechを比べてみたクラウドサービス、AWS/Azure/GCP それぞれの Text to Speechを比べてみた
クラウドサービス、AWS/Azure/GCP それぞれの Text to Speechを比べてみた
 
mrubyのすすめ
mrubyのすすめmrubyのすすめ
mrubyのすすめ
 

mrubyのJIT