1
/
5

RubyKaigi 2022 参加記 #9 - さまざまな最適化手法に関する発表 (Day2)

こんにちは、ソフトウェアエンジニアの千葉です。自分は RubyKaigi で Ruby コミッターそれぞれから今後の熱い展望を聞き、興奮冷めやらぬところですが、皆様はイカがお過ごしでしょうか。

今回、日本最大の 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 の2日目、たくさんの Ruby (と C) の話を聞いて心踊っているのですが、ここでは Ruby の最適化に関する発表を2つ、紹介させていただきます。

Method-based JIT compilation by transpiling to Julia

1つは、Kenta Murata さんによる 「Method-based JIT compilation by transpiling to Julia」です。

この発表は、JIT を用いた高速化についてなのですが、 (MJIT や YJIT とは異なる) 独自の JIT を実装し、対象のコードに Ruby の動的機能の一部を使用しないという制約のもと、大きな高速化を実現する、というものでした。

Method-based JIT compilation by transpiling to Julia
Chief Research Officer at XICA Co., Ltd. A committer of CRuby and Apache Arrow, and a member of Red Data Tools. A developer of pycall.rb, charty, unicode_plot.rb, enumerable-statistics, etc. A maintainer of bigdecimal.
https://rubykaigi.org/2022/presentations/Kenta%20Murata.html#day2

このアプローチのモチベーションとなったのが、Ruby で大規模な数値計算で行いたいというものでした。 Ruby 上で数値計算を実現するために、大規模なデータを扱うための (https://red-data-tools.github.io/ らによる) ライブラリの整備が進んでいたのですが、実現のボトルネックとなっ ていたのが、Ruby の一部の動的機能でした。

その例として、Ruby ではメソッドを動的に再定義することが行える、ということがあります。これ自体は便利に利用できる場面もあるのですが、動的に行えるためメソッドを実行するたびに再定義が行われているかのチェックを行う必要があるのですが、数値計算の場合、こうした機能を利用することは少ないし、チェックのためのオーバーヘッドがパフォーマンスに悪影響を与えていました。(もちろん C extension として実装すれば起きない問題ではありますが、 Ruby で数値計算処理を行いたいというモチベーションからは外れています。)

また、MJIT や YJIT は基本的に Ruby の仕様に忠実に動作するため、この問題に対応出来ていないとのことでした。

こうした問題を解決するために取ったアプローチというのが、「こうした動的機能を使わず、高速に処理したいコードを、 JIT により実行時に動的機能のチェックを行わない機械語にコンパイルし、実行する」というものでした。

このアプローチは numba という Python 用の JIT コンパイラで取られている手法です。

Numba: A High Performance Python Compiler
@njit( parallel=True) def simulator(out): # iterate loop in parallel for i in prange(out.shape[0]): out[i] = run_sim() Numba can automatically execute NumPy array expressions on multiple CPU cores and makes it easy to write parallel loops. LBB0_8: vmovups
https://numba.pydata.org/

numba は (以下のコードのように) decorator で指定した function に対して、Python の一部の機能が使えないという制約の代わりに、numba が最適化を行います。この手法を Ruby に持っていこうというのが今回のアイデアでした。

from numba import njit
import random

@njit
def monte_carlo_pi(nsamples):
    acc = 0
    for i in range(nsamples):
        x = random.random()
        y = random.random()
        if (x ** 2 + y ** 2) < 1.0:
            acc += 1
    return 4.0 * acc / nsamples

(https://numba.pydata.org/ より)

JIT コンパイルするには、 Ruby の AST または YARV のバイトコードを最適化しつつコンパイルするのをを行う必要があるのですが、これをフルスクラッチするのではなく、「難しいことは Julia にやらせよう」ということで、

Ruby の AST → Julia のコード → 機械語

という工程で、Ruby の AST から Julia のコードへの変換 (と言語間の差分の吸収) を行い、最適化及びコンパイルは Julia に任せる、というアプローチが取られていました。こうした設計で実装を行い、いくつかの数値計算プログラムでベンチマークを行ったところ、大幅な高速化が見られたとのことでした。

今回の実装の設計について解説している (と思われる) 内容は、今回の発表を行った Kenta Murata さんが以下のブログでまとめています。

Ruby を Julia に変換して実行すると速くなる (場合がある) - Speee DEVELOPER BLOG
開発部 R&D ユニットの村田です。OSSの開発をしております。本記事では、Ruby で書かれたマンデルブロ集合を計算するメソッドを実行時に Julia に変換して実行するとめっちゃ速くなる (場合がある)、という話をします。 Ruby 3.1 では YJIT がマージされ、 Rails アプリケーションが速くなりました。今後のバージョンアップがとても楽しみですね。ただし、Ruby のデータ処理対応を進めている身としては、データ処理や数値計算がより高速になって欲しいと思っています。 データ処理や数値計算を
https://tech.speee.jp/entry/transpiling-ruby-to-julia

RubyKaigi 1日目の k0kubun さんの発表で、「Ruby 3.2 で MJIT が Ruby 実装化し、モンキーパッチできるようになった」という話がありましたが、こうした、仕様に制約をもたせ、特定の分野に特化するような独自の JIT を実装してみる、というのも価値があり、非常に面白いかもしれません。

Implementing Object Shapes in CRuby

もう1つは Jemma Issroff さんの 「Implementing Object Shapes in CRuby」 です。これは CRuby に対し、現在導入が提案されている Object Shapes を用いた改善についての解説でした。

Implementing Object Shapes in CRuby
Object Shapes are a technique for representing properties of an object that can increase cache hits in instance variable lookups, decrease runtime checks, and improve JIT performance. In this talk, we'll learn all about the CRuby implementaion of Object S
https://rubykaigi.org/2022/presentations/jemmaissroff.html#day2

ここで提案されている Object Shape とは、「Ruby オブジェクトの形」を表現するデータ構造のことです。オブジェクトの形を表す情報として、「オブジェクトの持つインスタンス変数それぞれの名前」「freeze されているか」などの情報を持ちます。

これにより様々な恩恵があり、例えばインスタンス変数の取得をする際のキャッシュとすることで、これまでのクラス毎のキャッシュよりもヒットしやすくなり高速化になったり、様々なチェックの処理などをシンプルにしやすくできるそうです。実際に、一部のベンチマーク (継承したクラスインスタンスに対するインスタンス変数アクセス) では2倍程度の高速化になったそうです。

今回の発表に関連した Feature Request は以下で今回の改善について解説があり、 GitHub 上に Draft 実装もあります。

Feature #18776: Object Shapes - Ruby master - Ruby Issue Tracking System
Aaron Patterson, Eileen Uchitelle and I have been working on an implementation of Object Shapes for Ruby. We are filing a ticket to share what we've been doing, as well as get feedback on the project in its current state. We hope to eventually submit the
https://bugs.ruby-lang.org/issues/18776
Draft PR of the object shapes implementation by jemmaissroff · Pull Request #6248 · ruby/ruby
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subse
https://github.com/ruby/ruby/pull/6248

Object Shape については、去年の Rubykaigi でも TruffleRuby における最適化手法という形で紹介されています。この手法に関する研究、アイデアのルーツとして、プログラミング言語の Smalltalk や Self から始まったということも解説されています。

The Future Shape of Ruby Objects
These are the notes for a talk I gave at RubyKaigi 2021, which is why they're written as if we were talking and going through some slides and code together. Hello I'm Chris Seaton. I'm a Senior Staff Engineer at Shopify where I'm working on Ruby performan
https://chrisseaton.com/truffleruby/rubykaigi21/
Rubyオブジェクトの未来をつくる「シェイプ」とは(翻訳)|TechRacho by BPS株式会社
これはRubyKaigi 2021で行ったセッションの原稿につき、スライドやコードを見ながら話しているかのような口語体で書きました。 皆さんこんにちは、 Chris Seatonです。 ShopifyのシニアスタッフエンジニアとしてRubyのパフォーマンス研究に従事しており、非常に高度に最適化されたRuby実装である TruffleRubyを立ち上げました。また、Rubyに関する研究のまとめサイト『 The Ruby Bibliography(rubybib.org) 』も運営しています。 本日は、Tru
https://techracho.bpsinc.jp/hachi8833/2021_09_27/111656

今回紹介した内容はどちらも、他言語で過去に実用や研究されていた手法を、うまく利用して Ruby に落とし込んでいて、聞いていて非常にエンジニアとして心揺さぶられます…!

ちなみに、こうした改善の話など、RubyKaigi の発表を聞いていると、 Ruby の内部データ構造の話がめちゃくちゃ出ますが、Ruby のオブジェクトがどういうデータ構造になっているか、インスタンス変数はどう持っているかなどは、Rubyのしくみ Ruby Under a Microscope という書籍が参考になります。

Rubyのしくみ Ruby Under a Microscope
本書の関連ページが用意されています。 本書は、Rubyインタプリタを題材にプログラミング言語処理系の仕組みを解説するNo Starch Press社の"Ruby Under a Microscope" の翻訳発行です。 VMベースのインタプリタ型言語処理系であるRubyがコードをどのように解釈し、どうやって実行するか、そのしくみを解説。Rubyについての基礎知識がなくても、図版と短いコードの実験を多用した構成により、そのしくみについて理解することができます。 実務でRubyは使えるけれど、基礎知識について
https://tatsu-zine.com/books/ruby-under-a-microscope-ja

(発行されてからしばらく経つので古い内容もありますが)

RubyKaigi も残り1日、最終日も面白そうな発表が目白押しで楽しみですね!Wantedlyから参加したエンジニアが他の記事をまだまだ出していきます。そちらも御覧ください!

Wantedly, Inc.では一緒に働く仲間を募集しています
3 いいね!
3 いいね!
同じタグの記事
今週のランキング
Wantedly, Inc.からお誘い
この話題に共感したら、メンバーと話してみませんか?