Experimental feature in GraalVM

常见问题

TruffleRuby 是什么? #

TruffleRuby 是 Ruby 编程语言的一个高性能实现,它基于 GraalVM 构建,并使用了 Truffle 语言实现框架和 GraalVM 编译器。TruffleRuby 是 GraalVM 的一部分,GraalVM 是一个高性能多语言编程平台。

Truffle 是什么? #

Truffle 语言实现框架是一个用于编写 AST 解释器的 Java 框架。要使用 Truffle 实现一种语言,您需要为您的语言编写一个 AST,并添加方法来解释(即执行)每个节点的操作。

Truffle 还引入了特化(specialization)的概念。在大多数 AST 解释器中,节点是巨态的(megamorphic),它们处理所有可能的类型和其他可能的情况。而在 Truffle 框架中,您为相同的语义操作编写多个不同的节点,但针对不同的类型和条件。随着运行时条件的变化,您可以切换所使用的节点。程序预热后,您最终会得到一个精确地为实际使用的类型和条件定制的 AST。如果这些条件发生变化,您可以再次切换节点。

GraalVM 编译器是什么? #

GraalVM 编译器是 OpenJDK Java 虚拟机中即时编译器(JIT 编译器,通常我们称之为 动态编译器)的一个新实现。与现有编译器不同,Graal 是用 Java 编写的,并向运行中的程序公开 Java API。这意味着 JVM 语言可以直接控制编译器,而不是发出字节码。然而,这很复杂,因此 Truffle 框架通常会代表您使用 GraalVM 编译器,将您的 AST 解释器部分求值为机器代码。

GraalVM 是什么? #

GraalVM 是 TruffleRuby 运行的平台。它是一个高性能多语言编程系统。

更具体地说,GraalVM 是一个包含 GraalVM 编译器和 GraalVM Native Image 等额外组件的 JDK(Java 开发工具包)。GraalVM 编译器和 GraalVM Native Image 随后被 TruffleRuby 等 Truffle 语言使用。

如何获取 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 编译器的虚拟机? #

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 Community Edition 显著更快、内存效率更高。

如何判断我是否正在使用 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 中重新分叉出来。分叉也使我们能够简化代码库。

联系我们