1
/
5

RubyKaigi 2022 参加記 #2 - YJIT 開発チームからの発表 (Day1)

Photo by NASA on Unsplash

こんにちは、ソフトウェアエンジニアの千葉です。RubyKaigi の発表を聞いて心が踊ったり、明日の Splatoon 3 発売を控えて心が踊ったりしていて、心が三重とバンカラ地方を行ったり来たりしています。

今回、日本最大の Ruby に関するカンファレンスである RubyKaigi に Wantedly がスポンサードし、いくつかの講演を聴講させていただいています。(Wantedly はスポンサーブースを設けていて、エンジニアが執筆した技術書の配布等を行っていますので、もし興味があれば是非…🙏)

WantedlyはRubyKaigi2022にプラチナプランとして協賛し、技術書と開発に役立つHandbookをブースでプレゼントしています #rubykaigi | Wantedly, Inc.
こんにちは!Wantedlyで技術イベント企画まわりを担当しています竹内みずき (@amanda__mt)です! いよいよ本日から3日間、 RubyKaigi 2022 が開催されますね!私たちはこの度プラチナスポンサーとして協賛させていただき、三重県現地にて参加する運びとなりました。 直近2年間はほぼすべてのカンファレンスやイベントがオンラインでの開催となり、今回は久しぶりの ...
https://www.wantedly.com/companies/wantedly/post_articles/430335

RubyKaigi の初日、YJIT 開発チームのメンバー2人から、JIT に関しての発表がありました。非常に面白い発表だったのでそれぞれ紹介させていただきます。

Building a Lightweight IR and Backend for YJIT

1つ目は、Maxime Chevalier-Boisvert さんからの 「Building a Lightweight IR and Backend for YJIT」です。YJIT の x86 以外への対応、とりわけ ARM への対応についてでした。

YJIT (Yet Another Ruby JIT) は Shopify が開発し、 Ruby 3.1 で Ruby に試験的機能として組み込まれた機能です。 (YJIT がどのような機能なのか、どういう設計で動いているかについては、既に様々な解説が上がっているのでそちらをどうぞ)

ruby/yjit.md at v3_1_2 · ruby/ruby
DISCLAIMER: Please note that this project is experimental. It is very much a work in progress, it may cause your software to crash, and current performance results will vary widely, especially on larger applications. YJIT is a lightweight, minimalistic Ru
https://github.com/ruby/ruby/blob/v3_1_2/doc/yjit/yjit.md
Ruby が YJIT でなんで速くなるのか? Lazy Basic Block Versioning をサクッと理解してみた - estie inside blog
estie でソフトウェアエンジニアをしている徳永(@yTo_9)です。 estie では Ruby を書いたりTypeScriptを書いたりしています! estie 夏のブログ祭りにかこつけて、せっかくなら普段は追わない部分だけど、気になっていたYJITなるものを深掘りしてみようと思い、「YJITがなぜRailsアプリケーションの高速化を実現できたのか」を調べてみたので紹介したいと思います。 「どうせ難しいんでしょ?」と思いながら調べてみたのですが、講演や論文の説明がわかりやすく、意外に概要を把握するこ
https://inside.estie.co.jp/entry/2022/08/15/153357

YJIT は性能向上をもたらした一方、課題としてあったのは x86 でのみ利用可能という点でした。

YJIT は YARV (Yet Another Ruby VM) のバイトコードを x86 機械語への直接変換を行っていたため、 x86 に利用が限られていました。ただ、Apple Silicon や AWS Graviton, Raspberry Pi などの ARM 環境や他のプラットフォームでも Ruby は使われており、それらも YJIT の恩恵を受けられるように、まずは ARM64, 将来的に RISC-V などの他のプラットフォームに対応が行えるように、実装の刷新を行ったとのことでした。

新しい実装の主な特徴は、YARV (Yet Another Ruby VM) のバイトコードから機械語に直接変換するのではなく、一旦 IR (Intermediate Representation) への変換を行うという工程が増えたことです。YARV バイトコードから IR への変換を行った後、その IR に対して各プラットフォーム向けの最適化を行った上で、最終的に各プラットフォームの機械語に変換する、という設計になりました。これにより、複数プラットフォームへの対応が行いやすくなったとのことです。

発表中でも IR の instruction set についての紹介がありました。実際に Ruby 本体のリポジトリからどういった instruction set なのか、どういった実装なのかを見ることが出来ます。

ruby/ir.rs at 78af05ba0f29d1fc290dc24a6a5fb645386e7d62 · ruby/ruby
You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or window. Reload to refresh your session. Reload to refresh your session.
https://github.com/ruby/ruby/blob/78af05ba0f29d1fc290dc24a6a5fb645386e7d62/yjit/src/backend/ir.rs#L283-L448

(ちなみに、Ruby 3.1 で Ruby 本体に組み込まれた当時は、YJIT は C 実装だったのですが、Rust 実装に置き換えが行われています。その背景については Shopify の以下のブログをどうぞ)

YJIT: Building a New JIT Compiler for CRuby
The 1980s and 1990s saw the genesis of Perl, Ruby, Python, PHP, and JavaScript: interpreted, dynamically-typed programming languages which favored ease of use and flexibility over performance. In many ways, these programming languages are a product of the
https://shopify.engineering/yjit-just-in-time-compiler-cruby

この実装の刷新による ARM 対応、 もう (バグがまだあるとはいえ) 動く状態になっていて、(今年末に行われるであろう) Ruby 3.2 でリリースされるという状態らしく、そのスピード感には驚きです…。これだけの刷新を短期間で進める YJIT 開発チームの開発力は凄まじいものがありますね…。Ruby 3.2 以降もパフォーマンスの向上のための最適化が進められるということで今後が楽しみです。

Towards Ruby 4 JIT

2つ目は k0kubun さんからの、「Towards Ruby 4 JIT」で、こちらは、 MJIT, YJIT 両方のこれまでと今後について、Ruby 4 に向けての今後の目標とそれに向けてのチャレンジングな点が、非常にスピーディーに発表されました。

(既に発表に使われたスライドが Speaker Deck にアップロードされております。)


とりわけ非常に興味深かった点が、MJIT が Ruby 3.1 までは C 実装だったのが、3.2 以降は Ruby 実装になり、 (Secret な) 標準ライブラリとして提供されるようになる点です。

Ruby 実装になるということは、つまりモンキーパッチが可能ということで、発表では、実際にモンキーパッチする例として、RubyVM::MJIT#compile を差し替えて、fisk を利用しながら機械語を出力するように差し替えるモンキーパッチ、

class << RubyVM::MJIT
  def compile(iseq)
    buf = Fisk::Helpers.jitbuffer(4096)
    Fisk.new.asm(buf) do
      # pop stack frame
      add rsi, imm32(0x40)
      mov m64(rdi, 0x10), rsi
      # return true
      mov rax, imm64(0x14)
      ret
    end
    puts "JIT compile: #{iseq.body.location.label}"
    return buf.memory.to_i
  end
end
RubyVM::MJIT.resume

(https://speakerdeck.com/k0kubun/rubykaigi-2022?slide=23 より)

RubyVM::MJIT::Compiler#compile でコンパイラに食わせる C コードを変更するモンキーパッチ、

class << RubyVM::MJIT.const_get(:Compiler)
  def compile(f, _iseq, funcname, _id)
    c = RubyVM::MJIT.const_get(:C)
    c.fprintf(f, "VALUE #{funcname}(rb_execution_context_t *ec, rb_control_frame_t *cfp)\n{\n")
    c.fprintf(f, "    ec->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);\n")
    c.fprintf(f, "    return Qtrue;\n")
    c.fprintf(f, "}\n")
    return true
  end
end
RubyVM::MJIT.resume

(https://speakerdeck.com/k0kubun/rubykaigi-2022?slide=24 より)

などが紹介されていました。

これらを利用して、「ぼくのかんがえたさいきょうの JIT」を BYOJ (Bring Your Own JIT) してみたり、あえて壊して内部の仕様を理解したり、何かフックを仕込んでみたりするなど遊びがいがありそうです。非常に Ruby らしい、夢がある機能ですね………!!!

Ruby 3.1 → 3.2 で、YJIT が ARM にも対応されるようになり、MJIT は Ruby から触れるようになり、今後もさらなる最適化を行う予定など、 JIT の開発は勢いがあり、非常に今後が楽しみと感じさせる発表でした!

まだRubyKaigiは始まったばかりです。

Wantedlyから参加したエンジニアが他の記事をどんどん出していきます。そちらもぜひ御覧ください!


#3 次のブログへ👇

RubyKaigi 2022 参加記 #3 - Types teaches success, what will we do?(Day1) | Wantedly Engineer Blog
こんにちは、Wantedly で Web エンジニアをしている池田です。 弊社は RubyKaigi 2022をスポンサーしており、現地に5名のエンジニアが参加しています。先着でノベルティの Wantedly Handbook を配布しているのでもし興味があったらブースに遊びに行ってみてください。 自分はオンラインでの参加ですが、Types teaches success, what will we do?
https://www.wantedly.com/companies/wantedly/post_articles/430812
Wantedly, Inc.では一緒に働く仲間を募集しています
3 いいね!
3 いいね!
同じタグの記事
今週のランキング
Wantedly, Inc.からお誘い
この話題に共感したら、メンバーと話してみませんか?