Skip to content

Update documentation for native-by-default #1269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 41 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,40 @@ TruffleRuby aims to:
* Add fast and low-overhead interoperability with languages like JavaScript, Python and R
* All while maintaining very high compatibility with the standard implementation of Ruby

## TruffleRuby Configurations

There are two main configurations of TruffleRuby - *native* and *JVM*. It's
important to understand the different configurations of TruffleRuby, as each has
different capabilities and performance characteristics. You should pick the
execution mode that is appropriate for your application.

When distributed as part of GraalVM, TruffleRuby by default runs in the *native*
configuration. In this configuration, TruffleRuby is ahead-of-time compiled to a
standalone native executable. This means that you don't need a JVM installed on
your system to use it. The advantage of the native configuration is that it
[starts about as fast as MRI](doc/contributor/svm.md), it may use less memory,
and it becomes fast in less time. The disadvantage of the native configuration
is that you can't use Java tools like VisualVM, you can't use Java
interopability, and *peak performance may be lower than on the JVM*. The native
configuration is used by default, but you can also request it using `--native`.

TruffleRuby can also be used in the *JVM* configuration, where it runs as a
normal Java application on the JVM, as any other Java application would. The
advantage of the JVM configuration is that you can use Java interopability, and
*peak performance may be higher than the native configuration*. The disadvantage
of the JVM configuration is that it takes much longer to start and to get fast,
and may use more memory. The JVM configuration is requested using `--jvm`.

If you are running a short-running program you probably want the default,
*native*, configuration. If you are running a long-running program and want the
highest possible performance you probably want the *JVM* configuration, by using
`--jvm`.

You won't encounter it when using TruffleRuby from the GraalVM, but there is
also another configuration which is TruffleRuby running on the JVM but with the
Graal compiler not available. This configuration will have much lower
performance and should normally only be used for development.

## Documentation

Extensive documentation is available in [`doc`](doc).
Expand All @@ -57,35 +91,15 @@ set up a [UTF-8 locale](doc/user/utf8-locale.md).
## Current Status

TruffleRuby is progressing fast but is currently probably not ready for you to
try running your full Ruby application on.

TruffleRuby is ready for experimentation and curious end-users to try on their
gems and smaller applications.

### Common questions about the status of TruffleRuby

#### Do you run Rails?

We do run Rails, and pass the majority of the Rails test suite. But we are
missing support for OpenSSL, Nokogiri, and ActiveRecord database drivers
which makes it not practical to run real Rails applications at the moment.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this stay?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added quite a lot so I wanted to remove some. It's also out of date - support for OpenSSL is not missing. What do you think we should say?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Nokogiri is not fully integrated yet, and database drivers is work-in-progress, so I would keep it and just drop the OpenSSL part.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe something about C extensions where not all run out of the box.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing.


#### What is happening with native, startup time, and the SubstrateVM?

You don't need a JVM to run TruffleRuby. With the
[SubstrateVM](doc/user/svm.md)
it is possible to produce a single, statically linked native binary executable
version of TruffleRuby, which doesn't need any JVM to run.

This SubstrateVM version of TruffleRuby has startup performance and memory
footprint more similar to MRI than TruffleRuby on the JVM or JRuby. There are
[instructions](doc/user/svm.md)
for using it as part of GraalVM.
try running your full Ruby application on. However it is ready for
experimentation and curious end-users to try on their gems and smaller
applications.

#### Can TruffleRuby run on a standard JVM?
TruffleRuby runs Rails, and passes the majority of the Rails test suite. But it
is missing support for Nokogiri and ActiveRecord database drivers which makes it
not practical to run real Rails applications at the moment.

It is possible to [run on an unmodified JDK 10](doc/user/using-java10.md) but you
will have to build Graal yourself and we recommend using GraalVM instead.
You will find that many C extensions will not work without modification.

## Contact

Expand Down
117 changes: 117 additions & 0 deletions doc/contributor/svm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Using TruffleRuby with the SVM

The Substrate Virtual Machine, or SubstrateVM, is a closed- and whole-world
analysis ahead-of-time compiler for Java, and an implementation of parts of a
JVM.

We use the SVM to ahead-of-time compile TruffleRuby and the Graal dynamic
compiler to a single, statically-linked native binary executable, that has no
dependency on a JVM, and does not link to any JVM libraries. The technique is
more sophisticated than just appending a JAR as a resource in a copy of the JVM -
only parts of the JVM which are needed are included and they are specialised for
how TruffleRuby uses them. There is no Java bytecode - only compiled native
machine code and compiler graphs for dynamic compilation.

Note that a common confusion is that the SVM is an ahead-of-time compiler for
the Java code that implements the TruffleRuby interpreter and the Graal
compiler, not an ahead-of-time compiler for your Ruby program.

The SVM itself, like Graal and TruffleRuby, is implemented in Java.

https://youtu.be/FJY96_6Y3a4?t=10023

More information can be found in Kevin's
[blog post](http://nirvdrum.com/2017/02/15/truffleruby-on-the-substrate-vm.html).

The TruffleRuby that is distributed in the [GraalVM](../user/using-graalvm.md)
by default uses a version compiled using SVM - this is since version 0.33 of
GraalVM and was changed to prioritise fast start-up and warm-up time for shorter
running commands and benchmarks.

```bash
$ cd graalvm
$ otool -L jre/bin/ruby
jre/bin/ruby:
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1348.28.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)

$ du -h jre/bin/ruby
200M jre/bin/ruby
```

The SVM version of TruffleRuby has better startup performance and lower memory
footprint than TruffleRuby or JRuby on the JVM, and better startup performance
than Rubinius. We expect these numbers to improve significantly in the future as
we ahead-of-time compile more of the Ruby startup process, and aim to meet or
beat MRI's startup time.

| Implementation | Real Time (s) | Max RSS (MB) |
| -------------- | ------------: | -----------: |
| TruffleRuby SVM | 0.10 | 97 |
| TruffleRuby JVM | 2.86 | 272 |
| JRuby 9.1.13.0 | 1.44 | 154 |
| MRI 2.4.2 | 0.03 | 8 |
| Rubinius 3.84 | 0.25 | 65 |

Run on Linux with an Intel(R) Core(TM) i7-4702HQ CPU @ 2.20GHz.

```bash
$ export TIME="%e %M"

$ cd graalvm-0.28
$ /usr/bin/time bin/ruby --native -e 'puts "Hello"' # TruffleRuby on the SVM
Hello
0.10 99764

$ /usr/bin/time bin/ruby --jvm -e 'puts "Hello"' # TruffleRuby on the JVM
Hello
2.86 278240

$ chruby jruby-9.1.13.0
$ /usr/bin/time jruby -e 'puts "Hello"'
Hello
1.44 158080

$ chruby ruby-2.4.2
$ /usr/bin/time ruby -e 'puts "Hello"'
Hello
0.03 8672

$ chruby rbx-3.84
$ /usr/bin/time rbx -e 'puts "Hello"'
Hello
0.25 66824
```

(The first number `real` is the number of actual seconds which have elapsed
while the command runs, and the second `maximum resident set size` is the
maximum amount of memory occupied while the command runs.)

There is no need to do so, but you can actually also compile your own copy of
the SVM version of TruffleRuby using a tool distributed as part of GraalVM and
the Java version of TruffleRuby from GraalVM.

```
$ native-image -H:Name=native-ruby --Language:ruby
```

`native-ruby` is the output file name.

You can build a native image using SVM from a source distribution using:

```
$ jt build native
```

The disadvantages of the SVM version of TruffleRuby are:

* It has lower peak performance, as the GC is simpler and some optimisations
such as compressed ordinary object pointers (OOPS) are not yet available.
* You can't use Java interopability.
* You can't use standard Java tools like VisualVM.

So the SVM version may not be appropriate for all uses.

For the highest performance for long-running processes you want to use the
JVM version of TruffleRuby, using `--jvm`.
14 changes: 7 additions & 7 deletions doc/user/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,16 +226,16 @@ not clear if this will ever be a priority.
We do not have any plans at the moment to provide support for Rubinius'
extensions to Ruby.

## Features not yet supported on the SVM
## Features not yet supported in native configuration

* Java interop

Running TruffleRuby on the SVM is substantially the same as running on
GraalVM. There are differences in resource management, as both VMs use different
garbage collectors. But, functionality-wise, they are essentially on par
with one another. The big difference is support for Java interop, which
currently relies on reflection. TruffleRuby's implementation of Java interop
does not work with the SVM's limited support for runtime reflection.
Running TruffleRuby in the native configuration is mostly the same as running on
the JVM. There are differences in resource management, as both VMs use different
garbage collectors. But, functionality-wise, they are essentially on par with
one another. The big difference is support for Java interop, which currently
relies on reflection. TruffleRuby's implementation of Java interop does not work
with the SVM's limited support for runtime reflection.

## Spec Completeness

Expand Down
4 changes: 3 additions & 1 deletion doc/user/jruby-java-interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

JRuby provides a rich set of interop functionality between Ruby and Java, and we
attempt to emulate it faithfully in TruffleRuby.
Currently, this is supported when running on JVM but not on SubstrateVM.

You will need to use the JVM configuration, with `--jvm`, in order to use
JRuby-compatible Java interop.

## Ruby proxies for Java classes

Expand Down
13 changes: 12 additions & 1 deletion doc/user/reporting-performance-problems.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ that is unique to us - it applies to many sophisticated virtual machines - but
most Ruby implementations are not yet doing optimisations powerful enough to
show them so it may be a new problem to some people in the Ruby community.

## Using the JVM configuration

For the best peak performance, you want to use the JVM configuration, using
`--jvm`. The default native configuration starts faster but doesn't quite reach
the same peak performance. However, you *must* then use a good benchmarking
tool, like `benchmark-ips` described below, to run the benchmark, or the slower
warmup time will mean that you don't see TruffleRuby's true performance in the
benchmark. If you want to write simpler benchmarks that just run a while loop
with a simple timer (which we would not recommend anyway), then use the default
native mode so that startup and warmup time is shorter.

## How to check for basic performance problems

If you are examining the performance of TruffleRuby, we would recommend that you
Expand All @@ -34,7 +45,7 @@ try to work around errors and you will not see that there is a problem.
We recommend that you use
[`benchmark-ips`](https://github.com/evanphx/benchmark-ips), by Evan Phoenix, to
check the performance of TruffleRuby, and it makes things easier for us if you
report any potential performance problems using a report from `benchmark-ips`.
report any potential performance problems using a report from `benchmark-ips`.

A benchmark could look like this:

Expand Down
90 changes: 0 additions & 90 deletions doc/user/svm.md

This file was deleted.

10 changes: 6 additions & 4 deletions doc/user/using-graalvm.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ http://www.oracle.com/technetwork/oracle-labs/program-languages/

Inside the GraalVM is a `jre/languages/ruby` directory which has the usual
structure of a Ruby implementation. It is recommended to add this directory to
a Ruby manager, see [Configuring Ruby managers](ruby-managers.md) for more
a Ruby manager, see [configuring Ruby managers](ruby-managers.md) for more
information.

By default, GraalVM runs TruffleRuby on a JVM, but it can also run it on top
of the [SubstrateVM](svm.md) for faster startup-time but slower peak-performance.
This is enabled with the `--native` option.
By default, GraalVM runs TruffleRuby in the native configuration, which is best
for short-running processes, but it can also run it on top of the JVM which is
best for getting the highest peak performance and for Java interopability. Use
`--jvm` to use the JVM configuration. See the [readme](../../README.md) for
more information on different configurations.

You can also use GraalVM to run a different version of TruffleRuby than the one
it packages, but this not advised for end-users.
Loading