Experimental feature in GraalVM

常见问题解答

什么是 TruffleRuby? #

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

什么是 Truffle? #

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

Truffle 还包含了专业化的概念。在大多数 AST 解释器中,节点是巨型多态的 - 它们处理所有可能的类型和其他可能的情况。在 Truffle 框架中,您可以为同一个语义操作编写几个不同的节点,但针对不同的类型和条件。随着运行时条件的变化,您可以切换使用的节点。在程序预热后,您应该最终获得一个专门针对您实际使用的类型和条件的 AST。如果这些条件发生变化,您只需再次切换节点。

什么是 GraalVM 编译器? #

GraalVM 编译器是 OpenJDK Java 虚拟机中的一种新的即时编译器(JIT 编译器,或者我们通常所说的动态编译器)实现。与当前的编译器不同,Graal 是用 Java 编写的,并向正在运行的程序公开 Java API。这意味着 JVM 语言可以直接控制编译器,而不是发出字节码。但是,这很复杂,因此通常 Truffle 框架会代表您使用 GraalVM 编译器对您的 AST 解释器进行部分评估以生成机器代码。

什么是 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 框架还提供了一些 JVM 功能的包装器,这些功能通常不适用于 Java 应用程序,例如代码反优化。TruffleRuby 利用它来提供更简单、更快的 Ruby 实现。

这段代码来自哪里? #

Chris Seaton 在 2013 年上半年在 Oracle Labs 实习期间编写了 Truffle 和 Graal 上的 Ruby 实现。这段代码于 2014 年初合并到 JRuby 中。Benoit Daloze 和 Kevin Menard 于 2014 年下半年加入成为研究员,然后是 2015 年的 Petr Chalupa,2016 年的 Brandon Fish 以及 2017 年的 Duncan MacGregor。从那时起,我们也接受了 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 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 的核心部分时,我们将其分离出来。分离还允许我们简化我们的代码库。

与我们联系