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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
15
Improving my own Ruby thereafter
sisshiki1969
1
250
あなたとJIT, 今すぐアセンブ ル
sisshiki1969
1
1k
Improve my own Ruby
sisshiki1969
1
580
Running Optcarrot (faster) on my own Ruby.
sisshiki1969
1
320
仮想マシンにおけるスタックの管理
sisshiki1969
0
240
Rustでゴミ集め
sisshiki1969
1
380
RustでつくるRubyのFiber
sisshiki1969
0
320
Shinjuku.rs#15 Rustでつくるx86アセンブラ
sisshiki1969
0
1.8k
Featured
See All Featured
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.1k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
220
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
300
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
360
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.7k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
210
30 Presentation Tips
portentint
PRO
1
350
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
410
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
200
Agile that works and the tools we love
rasmusluckow
331
22k
Discover your Explorer Soul
emna__ayadi
2
1.2k
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.