Experimental feature in GraalVM

常見問題

什麼是 TruffleRuby? #

TruffleRuby 是 Ruby 程式語言的高效能實作,建立在 GraalVM 之上,並使用 Truffle 語言實作框架和 GraalVM 編譯器。TruffleRuby 是 GraalVM 的一部分,GraalVM 是一個高效能多語言程式設計平台。

什麼是 Truffle? #

Truffle 語言實作框架是一個 Java 框架,用於撰寫 AST 解譯器。若要使用 Truffle 實作語言,您需要為您的語言撰寫 AST,並新增方法來解譯 (執行動作) 每個節點。

Truffle 也採用特製化的概念。在大多數 AST 解譯器中,節點是多態的 – 它們處理所有可能的類型和其他可能的條件。在 Truffle 框架中,您為相同的語意動作撰寫數個不同的節點,但用於不同的類型和條件。隨著執行階段條件變更,您會切換您正在使用的節點。在程式暖機之後,您應該會得到一個精確為您實際使用的類型和條件量身打造的 AST。如果這些條件變更,您可以再次切換節點。

什麼是 GraalVM 編譯器? #

GraalVM 編譯器是 OpenJDK Java 虛擬機器中即時編譯器 (JIT 編譯器,或我們通常稱之為動態編譯器) 的新實作。與目前的編譯器不同,Graal 是以 Java 撰寫,並向執行中的程式公開 Java API。這表示 JVM 語言可以不用發出位元碼,而是直接控制編譯器。然而,這很複雜,因此通常 Truffle 框架會代表您在您的 AST 解譯器中部分評估 GraalVM 編譯器,將其轉換為機器碼。

什麼是 GraalVM? #

GraalVM 是 TruffleRuby 運作的平台。它是一個用於高效能多語言程式設計的系統。

更具體地說,GraalVM 是一個 JDK (Java 開發套件),具有額外元件,例如 GraalVM 編譯器和 GraalVM Native Image。然後,Truffle 語言 (例如 TruffleRuby) 會使用 GraalVM 編譯器和 GraalVM Native Image。

我如何取得 TruffleRuby? #

有多種方法可以安裝 TruffleRuby,請參閱開始使用

為什麼 TruffleRuby 在標準 JVM 上速度很慢? #

執行 TruffleRuby 的預期方式是使用 GraalVM 編譯器。TruffleRuby 並非設計為在沒有編譯器的 JVM 上有效率。

為什麼 TruffleRuby 在 GraalVM 上速度更快? #

當使用 GraalVM 編譯器執行時,Truffle 框架可以使用 GraalVM 編譯器公開的 API。Truffle 框架會取得執行您的 Ruby 方法所涉及的所有 AST 解譯器方法的位元碼表示法,將它們組合成類似單一 Java 方法的內容,將它們一起最佳化,並發出單一機器碼函式。Truffle 框架也為 Java 應用程式通常無法使用的 JVM 功能 (例如程式碼反最佳化) 提供包裝函式。TruffleRuby 使用此方法來提供更簡單且更快速的 Ruby 實作。

此程式碼的來源為何? #

Chris Seaton 在 2013 年上半年於 Oracle Labs 實習期間撰寫了在 Truffle 和 Graal 上實作 Ruby 的程式碼。該程式碼在 2014 年初合併到 JRuby 中。Benoit Daloze 和 Kevin Menard 在 2014 年下半年加入擔任研究員,然後 Petr Chalupa 在 2015 年加入,Brandon Fish 在 2016 年加入,而 Duncan MacGregor 在 2017 年加入。從那時起,我們也接受了來自 Oracle Labs 以外的人員的貢獻。在 2017 年,該程式碼在成熟後重新從 JRuby 分支出來。

我應該詢問誰有關 TruffleRuby 的問題? #

請參閱此README頁面的「聯絡方式」章節。

我如何知道自己是否正在使用 TruffleRuby? #

RUBY_ENGINE 將會是 'truffleruby'

我如何知道自己是否正在使用具有 GraalVM 編譯器的 VM? #

ruby --version 將會回報 GraalVM CEOracle GraalVM。23.0 之前的 TruffleRuby 版本會回報 GraalVM EE 而不是 Oracle GraalVM

此外,TruffleRuby.jit? 會告訴您是否正在使用 GraalVM 編譯器執行。

什麼是 Oracle GraalVM? #

Oracle GraalVM 是 Oracle 提供的 GraalVM 發行版,可在GraalVM 免費條款與條件下取得。Oracle GraalVM 提供最佳的 TruffleRuby 體驗:它比 GraalVM 社群版快得多,而且更省記憶體。

我如何知道自己是否正在使用 GraalVM 的社群版? #

ruby --version 將會回報 GraalVM CE

我如何知道自己是否正在使用 Oracle GraalVM? #

ruby --version 將會回報 Oracle GraalVM。23.0 之前的 TruffleRuby 版本會回報 GraalVM EE

我如何知道自己是否正在使用 TruffleRuby 的原生版本? #

ruby --version 將會回報 Native

TruffleRuby.native? 將會傳回 true

我如何查看 GraalVM 編譯器是否正在運作? #

將此程式放入 test.rb

loop do
  14 + 2
end

我們將使用 --engine.TraceCompilation 來要求 Truffle 框架在它使用 GraalVM 編譯器編譯某些內容時告知我們。

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 在我的基準測試中效能不佳? #

我們尚未研究過的基準測試可能需要新的程式碼路徑進行特製化。目前我們已為我們一直在使用的基準測試和應用程式中的程式碼路徑新增特製化。新增它們通常不複雜,而且隨著時間的推移,我們將擁有可涵蓋廣泛應用程式的特製化。

請確保您正在使用Oracle GraalVM以獲得最佳效能。

TruffleRuby 不使用 invokedynamic,因為它不會發出位元碼。然而,它確實具有最佳化的方法分派機制,可達成類似的結果。

為什麼 JRuby 不也切換到 Truffle? #

JRuby 正在採取不同的方法來最佳化 Ruby 和新增功能。JRuby 和 TruffleRuby 都是重要的專案。

為什麼您要從 JRuby 分支出來? #

我們合併到 JRuby 中,以便能夠使用其 Java 實作程式碼的很大一部分。當我們已達到我們正在使用的程式碼需要為我們的目的進行修改,而且我們不再依賴 JRuby 的核心部分時,我們就重新從 JRuby 分支出來。分支也讓我們的程式碼庫得以簡化。

與我們聯絡