Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
My own Ruby, thereafter
Search
monochrome
September 01, 2024
410
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
My own Ruby, thereafter
monochrome
September 01, 2024
More Decks by monochrome
See All by monochrome
RubyKaigi2026: Invariants in my own Ruby
sisshiki1969
0
13
Improving my own Ruby thereafter
sisshiki1969
1
240
あなたとJIT, 今すぐアセンブ ル
sisshiki1969
1
1k
Improve my own Ruby
sisshiki1969
1
570
Running Optcarrot (faster) on my own Ruby.
sisshiki1969
1
310
仮想マシンにおけるスタックの管理
sisshiki1969
0
240
Rustでゴミ集め
sisshiki1969
1
380
RustでつくるRubyのFiber
sisshiki1969
0
320
Shinjuku.rs#15 Rustでつくるx86アセンブラ
sisshiki1969
0
1.7k
Featured
See All Featured
RailsConf 2023
tenderlove
30
1.5k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
490
Heart Work Chapter 1 - Part 1
lfama
PRO
7
36k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.5k
Mind Mapping
helmedeiros
PRO
1
250
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
150
My Coaching Mixtape
mlcsv
0
150
Automating Front-end Workflow
addyosmani
1370
210k
Tell your own story through comics
letsgokoyo
1
960
How to Talk to Developers About Accessibility
jct
2
240
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Transcript
My own Ruby, thereafter monochrome @s_isshiki1969 sisshiki1969
monoruby 1. GitHub - sisshiki1969/monoruby: Ruby implementation with yet another
JIT compiler. 2. Rustで書かれたRuby処理系(個人&趣味開発) 3. インタプリタ・JITコンパイラを装備 4. パーサ・GCも独自開発 5. x86-64 / Linux のみサポート 6. 結構速い 7. RubyGems(読み込み)をサポートした
Benchmark results (yjit-bench)
Rubyプログラム バイトコード・コンパイラ パーサ AST バイトコード
JITコード (機械語) 移行 トレース実行 deoptimize バイトコード インタプリタ JITコンパイラ
0xaa %dst %lhs %rhs 左辺のクラスID 右辺のクラスID 0x01 %dst CallsiteId 前回の関数ID
METHOD_CALL 0x82 %rcv %args pos ADD_RR 8 bytes 8 bytes バイトコード レシーバクラスID タイムスタンプ オペコード オペランド 実行時情報 inline method cache (前回実行時の情報)
Floatの演算の最適化 • Floatクラスの演算は遅い • 左辺 + 右辺 ◦ メモリから両辺のRubyオブジェクトを取ってくる ◦
両辺をdoubleに変換 ◦ doubleの加算 ◦ 結果をdoubleからRubyオブジェクトへ変換 ◦ メモリへ格納
Float or Integer any 3.14 3.14 xmm-n Float 3.14 xmm-n
3.14 any Literal(3.14) Stack-xmm(n) xmm(n) Stack クラス 状態 スタック 浮動小数点数 レジスタ (xmm) state of registers
:00001 %2 = literal[3.14] :00002 const[PI] = %2 :00003 %1
= 10: i32 :00004 %2 = const[PI] [3.14] :00005 %2 = %2 * %1 [Float][Integer] :00006 %2 = %2 * %1 [Float][Integer] :00007 %2 = %0.puts(%2;1) [#<Class:main>] :00009 ret %2 PI = 3.14 radius = 10 #something(evil) puts PI * radius * radius sample.rb bytecode
:00001 %2 = literal[3.14] :00002 const[PI] = %2 :00003 %1
= 10: i32 :00004 %2 = const[PI] [3.14] :00005 %2 = %2 * %1 [Float][Integer] :00006 %2 = %2 * %1 [Float][Integer] :00007 %2 = %0.puts(%2;1) [#<Class:main>] :00009 ret %2 Literal(10) %1 %2 Stack
:00001 %2 = literal[3.14] :00002 const[PI] = %2 :00003 %1
= 10: i32 :00004 %2 = const[PI] [3.14] :00005 %2 = %2 * %1 [Float][Integer] :00006 %2 = %2 * %1 [Float][Integer] :00007 %2 = %0.puts(%2;1) [Object] :00009 ret %2 3.14 3.14 Literal(10) %1 %2 Stack-xmm 00054: mov rax,QWORD PTR [rip+0x1ffd69d9] 0005b: cmp rax,QWORD PTR [rip+0x1ffd8dc2] 00062: jne 0xfff324c 00068: movq xmm2,QWORD PTR [rip+0x114] 00070: movabs rax,0x48f5c28f5c28fa 0007a: mov QWORD PTR [r14-0x40],rax xmm2
:00001 %2 = literal[3.14] :00002 const[PI] = %2 :00003 %1
= 10: i32 :00004 %2 = const[PI] [3.14] :00005 %2 = %2 * %1 [Float][Integer] :00006 %2 = %2 * %1 [Float][Integer] :00007 %2 = %0.puts(%2;1) [Object] :00009 ret %2 10 3.14 3.14 Stack-xmm %1 %2 Stack-xmm 0007e: mov QWORD PTR [r14-0x38],0x15 00086: movq xmm3,QWORD PTR [rip+0x106] 10.0 xmm2 xmm3
:00001 %2 = literal[3.14] :00002 const[PI] = %2 :00003 %1
= 10: i32 :00004 %2 = const[PI] [3.14] :00005 %2 = %2 * %1 [Float][Integer] :00006 %2 = %2 * %1 [Float][Integer] :00007 %2 = %0.puts(%2;1) [Object] :00009 ret %2 10 3.14 3.14 Stack-xmm %1 %2 Stack-xmm 0007e: mov QWORD PTR [r14-0x38],0x15 00086: movq xmm3,QWORD PTR [rip+0x106] 0008e: movq xmm4,xmm2 00092: mulsd xmm4,xmm3 10.0 31.4 xmm2 xmm3 xmm4
:00001 %2 = literal[3.14] :00002 const[PI] = %2 :00003 %1
= 10: i32 :00004 %2 = const[PI] [3.14] :00005 %2 = %2 * %1 [Float][Integer] :00006 %2 = %2 * %1 [Float][Integer] :00007 %2 = %0.puts(%2;1) [Object] :00009 ret %2 10 3.14 3.14 Stack-xmm %1 %2 xmm 10.0 31.4 xmm4 xmm2 xmm3 0007e: mov QWORD PTR [r14-0x38],0x15 00086: movq xmm3,QWORD PTR [rip+0x106] 0008e: movq xmm4,xmm2 00092: mulsd xmm4,xmm3
:00001 %2 = literal[3.14] :00002 const[PI] = %2 :00003 %1
= 10: i32 :00004 %2 = const[PI] [3.14] :00005 %2 = %2 * %1 [Float][Integer] :00006 %2 = %2 * %1 [Float][Integer] :00007 %2 = %0.puts(%2;1) [Object] :00009 ret %2 10 3.14 Stack-xmm %1 %2 xmm 00096: mulsd xmm4,xmm3 10.0 314.0 xmm3 xmm4
:00001 %2 = literal[3.14] :00002 const[PI] = %2 :00003 %1
= 10: i32 :00004 %2 = const[PI] [3.14] :00005 %2 = %2 * %1 [Float][Integer] :00006 %2 = %2 * %1 [Float][Integer] :00007 %2 = %0.puts(%2;1) [Object] :00009 ret %2 10 314.0 Stack-xmm %1 %2 Stack-xmm ... 000cf: movq xmm0,xmm4 000d3: call 0xfffd6ad5 000d8: mov QWORD PTR [r14-0x40],rax ... 0014c: call 0xfffdb8d5 ... 0016b: test rax,rax 0016e: je 0xfff32f0 00174: mov r15,rax 10.0 314.0 xmm3 xmm4
- 基本ブロックが分岐する部位では状態を コピーする - 合流する部位では状態を合成する処理を 行う - ループに関してはまず先頭へ戻る枝を計 算し、外部から流入する枝との合成を行 う(ループの先頭部分に関してのみ生存
解析を行っている) a a’ a’ a’ b c d d’ d’ s
PI = 3.14 radius = 10 something(evil) puts PI *
radius * radius something evil is coming... =>314
PI = 3.14 radius = 10 something(evil) puts PI *
radius * radius alias something eval evil = “PI = ‘!’” =>!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!
enemies of optimization 1. ブロック付きメソッド呼び出し 2. evalとその仲間たち 3. Proc 4.
Binding 5. 基本演算メソッド再定義(Integer#+, ...) 6. TracePoint 7. ObjectSpace
enemies of optimization 1. ブロック付きメソッド呼び出し 2. evalとその仲間たち 3. Proc 4.
Binding 5. 基本演算メソッド再定義(Integer#+, ...) 6. TracePoint 7. ObjectSpace 実行時に検出してJITコードのパージ・イン タプリタの書き換え 値をスタックへ書き戻し 実行時に検出してインタプリタへ戻る
Special thanks: @ko1, @k0kubun,@mametter @yhara, @raviqqe Run XXX on your
own Ruby.