よくある質問

TruffleRubyとは何ですか。

TruffleRubyは、Truffle言語実装フレームワークとGraalVMコンパイラを使用してGraalVM上に構築された、Rubyプログラミング言語の高パフォーマンス実装です。TruffleRubyは、高パフォーマンスのポリグロット・プログラミングのためのプラットフォームであるGraalVMの一部です。

Truffleとは何ですか。

Truffle言語実装フレームワークは、ASTインタプリタを記述するためのJavaフレームワークです。Truffleを使用して言語を実装するには、言語のASTを記述し、それぞれのノードを解釈する(ノードのアクションを実行する)メソッドを追加します。

また、Truffleには特殊化という概念も組み込まれています。ほとんどのASTインタプリタでは、ノードはメガモフィックであり、可能性のあるすべての型および可能性のある他の条件を処理します。Truffleフレームワークでは、同じセマンティック・アクションについて、型および条件が異なる様々なノードを記述します。ランタイム条件の変化に応じて、使用するノードを切り替えます。プログラムがウォームアップした後、最終的に、実際に使用している型と条件に従ってASTが正確に調整されます。これらの条件が変化した場合は、単にノードを再度切り替えます。

GraalVMコンパイラとは何ですか。

GraalVMコンパイラは、OpenJDK Java仮想マシンのJust-in-Timeコンパイラ(JITコンパイラ、または一般的には動的コンパイラ)の新しい実装です。現在のコンパイラとは異なり、GraalはJavaで記述され、実行中のプログラムにJava APIを公開します。つまり、バイトコードを生成するかわりに、JVM言語でコンパイラを直接制御できます。ただし、これは複雑であるため、通常は、Truffleフレームワークがユーザーに代わってGraalVMコンパイラを使用してASTインタプリタを部分的に評価し、マシン・コードに変換します。

GraalVMとは何ですか。

GraalVMは、TruffleRubyを実行するプラットフォームです。これは、高パフォーマンスのポリグロット・プログラミングのためのシステムです。

より具体的には、GraalVMは、Truffleフレームワーク、GraalVMコンパイラ、TruffleRuby、およびGraalVMでサポートされている他の言語(JavaScript、Python、Rなど)を含むOracleJDKの修正版です。

GraalVMおよびTruffleRubyのインストール方法を参照してください。

TruffleRubyを入手するにはどうすればよいですか。

TruffleRubyを入手するには、3つの方法があります。「スタート・ガイド」を参照してください。

標準JVMでTruffleRubyが低速なのはなぜですか。

TruffleRubyはGraalVMコンパイラを使用して実行することが想定されています。TruffleRubyは、そうでない方法でJVMで効率的に動作するようには設計されていません。

GraalVMではTruffleRubyが高速になるのはなぜですか。

GraalVMコンパイラを使用して実行すると、Truffleフレームワークは、GraalVMコンパイラによって公開されたAPIを使用できます。Truffleフレームワークは、Rubyメソッドの実行に関与するすべてのASTインタプリタ・メソッドのバイトコード表現を取得し、それらを単一のJavaメソッドのように組み合せてそれらをまとめて最適化し、単一のマシン・コード関数を生成します。また、Truffleフレームワークには、コードの最適化解除など、通常はJavaアプリケーションで使用できないJVM機能のラッパーも用意されています。TruffleRubyでは、これを使用して、飛躍的に簡略化および高速化されたRubyの実装を提供します。

このコードの来歴を教えてください。

Chris Seatonが2013年の前半に、Oracle Labsでのインターンシップの一環として、TruffleおよびGraal上でRubyの実装を記述しました。このコードが2014年初頭にJRubyにマージされました。2014年の後半にBenoit DalozeとKevin Menardが研究者として加わり、その後、2015年にはPetr Chalupa、2016年にはBrandon Fish、2017年にはDuncan MacGregorが加わりました。それ以降、Oracle Labsの外部の方々からの貢献も受け入れてきました。2017年に、コードが成熟した後、JRubyから再びフォークしました。

TruffleRubyに関する問合せ先はどこですか。

このREADMEページの「お問合せ」の項を参照してください。

TruffleRubyを使用しているかどうかはどうすればわかりますか。

RUBY_ENGINE'truffleruby'になります。

GraalVMコンパイラを備えたVMを使用しているかどうかはどうすればわかりますか。

ruby --versionによって、GraalVM CEまたはEEが報告されます。

また、TruffleRuby.jit?によって、GraalVMコンパイラを使用して実行しているかどうかがわかります。

GraalVMのCommunity Editionを使用していることはどうすればわかりますか。

ruby --versionによって、GraalVM CEが報告されます。

GraalVMのEnterprise Editionを使用していることはどうすればわかりますか。

ruby --versionによって、GraalVM EEが報告されます。

TruffleRubyのネイティブ・バージョンを使用していることはどうすればわかりますか。

ruby --versionによって、Nativeが報告されます。

TruffleRuby.native?によって、trueが返されます。

GraalVMコンパイラが動作していることを確認するにはどうすればよいですか。

次のプログラムをtest.rbに配置します:

loop do
  14 + 2
end

--engine.TraceCompilationを使用して、TruffleフレームワークがGraalVMコンパイラを使用して何かをコンパイルしたときに知らせるようTruffleに指示します。

ruby --engine.TraceCompilation test.rb
[truffle] opt done         block in <main> test.rb:1 <opt> <split-3a9ffa1b>         |ASTSize       8/    8 |Time   103(  99+4   )ms |DirectCallNodes I    0/D    0 |GraalNodes    24/    3 |CodeSize           69 |CodeAddress 0x11245cf50 |Source   ../test.rb:1

ここでは、TruffleがGraalVMコンパイラを使用して127のブロックをコンパイル(ループをマシン・コードにコンパイル)することを決定したことがわかります(マシン・コードは全部でわずか69バイトです)。

あるベンチマークに関してTruffleRubyのパフォーマンスが十分でないのはなぜですか。

まだ検討していないベンチマークでは、新しいコード・パスの特殊化が必要になる場合があります。現時点で、使用しているベンチマークおよびアプリケーションのコード・パスについては特殊化を追加しています。一般的に、これらを追加することは複雑ではなく、今後、幅広いアプリケーションを網羅するように特殊化を追加していく予定です。

最良のパフォーマンスを実現するために、GraalVMのEnterprise Editionを使用していることと、実行可能イメージを再ビルドしたことを確認してください。

TruffleRubyはバイトコードを生成しないため、invokedynamicを使用しません。ただし、同様の結果を達成する最適化メソッド・ディスパッチ・メカニズムを備えています。

JRubyもTruffleに切り替わらないのはなぜですか。

JRubyは、最適化とRubyへの新機能の追加に対して異なるアプローチを採用しています。JRubyとTruffleRubyはどちらも重要なプロジェクトです。

JRubyからフォークしたのはなぜですか。

Java実装コードの大部分を使用できるようにJRubyにマージしました。使用していたコードを独自の目的で変更することが必要になり、JRubyのコア部分に依存しなくなった時点で、JRubyから再びフォークしました。フォークにより、コード・ベースの簡素化も可能になりました。