Live data from Hacker News

Ruby YJIT Ported to Rust

github.com

71–80 of 93 posts

Re: Ruby YJIT Ported to Rust

#71
post #66

Earlier quoted context omitted.

I've been around for a long time and I haven't seen a PL with this much momentum since Java was launched. Inertia is real, but the benefits over C++ are undeniable. Bootstrapping seems a silly thing to be obsessed about as C++ will be around forever still, but it obviously can be bootstrapped if that becomes important.

Ada/SPARK already provided such benefits, and NVidia has chosen it instead of Rust for automotive firmware. Rust momentum is meaningless for GPUs unless NVidia decides it gets to play in CUDA, and they are now one of the companies with more ISO C++ people on their payroll. It is also meaningless for PlayStation, Nintendo and Xbox, unless the respective SDKs integrate Rust. Bootstraping isn't silly, because LLVM and G…

SPARK doesn't provide the same feature set as Rust. If you want safe heap allocation in SPARK, then you get a garbage collector (unless you're talking really recent experimental extensions IIRC). If you want to forego the GC and remain memory-safe, then you also forego heap allocation. This might work for avionics code, but not for most apps.

Besides, the post you're replying to is talking about "momentum", and it's obvious in 2022 that Ada doesn't have the momentum that Rust does (however you define "momentum"). NVIDIA is not the entire industry.

Much of the rest of your post concerns video games, which are only a small portion of the total C++ code in existence. (And in any case it's not accurate to say that languages are "meaningless" unless the platform vendor officially supports them—console vendors don't maintain C# VMs either and yet Unity titles work just fine.)

Re: Ruby YJIT Ported to Rust

#72
post #47
post #30

Earlier quoted context omitted.

Rust will eclipse C++. C is a harder nut to crack, particularly for the embedded space where ease of implementing and maintaining a compiler back-end/code-emitter for your new weird 8-bit architecture is important. C is pretty close to an assembly macro and it's barely updated, which is great for that use-case. But for use cases like interpreters Rust is perfectly suitable.

Good luck with that on anything GPU or HPC related, or industries with language standards. Also until Rust compilers are bootstraped, they will always rely on a C++ infrastructure.

WebRender is certainly "GPU related" and is shipping to millions of happy Firefox users.

And yes, LLVM is written in C++. So what? C++ compilers depend on C code in libc. Portions of libc are written in assembler. Some assembly instructions are decomposed into microcode. Yet nobody doubts that C++ has eclipsed assembly language in terms of importance to the industry nowadays. We'll always need a way for humans to read the actual instructions that the silicon interprets, but relatively few people need to be able to do that nowadays. That dynamic is what the parent post means by one language "eclipsing" another.

Re: Ruby YJIT Ported to Rust

#73

Here's a benchmark [1] done in Jan'22 against many ruby implementations, truffleRuby [2] seems to be way ahead in most, and at least ahead in all. Why truffleRuby isn't talk about much here? [1] https://eregon.me/blog/2022/01/06/benchmarking-cruby-mjit-yj... [2] https://github.com/oracle/truffleruby

When I read about its performance, I had the same thoughts, however, I was surprised to read this in the Github project readme: > TruffleRuby might not be fast yet on Rails applications and large programs. Notably, large programs currently take a long time to warmup on TruffleRuby and this is something the TruffleRuby team is currently working on. Large programs often involve more performance-critical code so there i…

This is always a problem for any JIT. Large codebases, especially ones as heavy on dynamic code paths as rails, run individual pieces of code less frequently than smaller ones (because they're just doing more work in general, and in rails' case are constantly spawning new code to deal with).

Then you have to instrument the code while it's running under a VM to decide what (and how) to JIT, and then you have to compile and assemble it. You also probably have to deal with some quasi-locking around the call sites as you switch code from using the VM to using the JIT.

So, basically by the laws of thermodynamics, all else equal a JITing VM will be slower than a non-JITing one, and the benefits of JIT won't kick in until you have enough code instrumented and compiled to make a dent in that performance loss from the extra work.

And then, the cleverer your JIT, and the more you optimize the code under compile, the more off-balance this gets, because doing those things gets more expensive.

Re: Ruby YJIT Ported to Rust

#74
post #2

"YJIT code ported from C99 to Rust" Beyond passing the test suite, are there more numbers to compare both versions? (e.g., compilation time, lines of code, size of binaries, performance, etc.)

The PR itself says: > The new Rust version of YJIT has reached parity with the C version, in that it passes all the CRuby tests, is able to run all of the YJIT benchmarks, and performs similarly to the C version (because it works the same way and largely generates the same machine code). We've even incorporated some design improvements, such as a more fine-grained constant invalidation mechanism which we expect will…

RoR comparison benchmarks would be nice to see.

Re: Ruby YJIT Ported to Rust

#75
post #66

Earlier quoted context omitted.

Ada/SPARK already provided such benefits, and NVidia has chosen it instead of Rust for automotive firmware. Rust momentum is meaningless for GPUs unless NVidia decides it gets to play in CUDA, and they are now one of the companies with more ISO C++ people on their payroll. It is also meaningless for PlayStation, Nintendo and Xbox, unless the respective SDKs integrate Rust. Bootstraping isn't silly, because LLVM and G…

SPARK doesn't provide the same feature set as Rust. If you want safe heap allocation in SPARK, then you get a garbage collector (unless you're talking really recent experimental extensions IIRC). If you want to forego the GC and remain memory-safe, then you also forego heap allocation. This might work for avionics code, but not for most apps. Besides, the post you're replying to is talking about "momentum", and it's…

What garbage collector? Ada never had one, besides the optional one in early standards, never implemented in any commercial compiler, thus removed in Ada 2012.

I wasn't the one asserting momentum, and can relate to plenty of other industries where Rust isn't even on the radar.

Going back to Ada example, Rust certainly doesn't have any momentum over Ada in high integrity computing.

Console vendors do happen to collaborate with Unity, and make it first party on their SDKs, so yet another lack of information.

Re: Ruby YJIT Ported to Rust

#76
post #47

Earlier quoted context omitted.

Good luck with that on anything GPU or HPC related, or industries with language standards. Also until Rust compilers are bootstraped, they will always rely on a C++ infrastructure.

WebRender is certainly "GPU related" and is shipping to millions of happy Firefox users. And yes, LLVM is written in C++. So what? C++ compilers depend on C code in libc. Portions of libc are written in assembler. Some assembly instructions are decomposed into microcode. Yet nobody doubts that C++ has eclipsed assembly language in terms of importance to the industry nowadays. We'll always need a way for humans to rea…

For how long? 3% and decreasing.

Libc is UNIX only.

As for the rest, it is useful to tone down hype with some cold water reality check.

Re: Ruby YJIT Ported to Rust

#77
post #33

I found this part odd > . If YJIT is built in dev mode, then cargo is used to fetch development dependencies, but when building in release, cargo is not required, only rustc I'm not finding any information on why they bypass cargo and build directly with rustc. I'm curious what requirements led to this.

Cargo is .. not a pleasant build tool to integrate into other build systems. If you have a project (like mainline ruby) where the dominant mode is C and you need to integrate some rust into it, you will eventually feel like it'd be a useful use of your time to bypass cargo and use the compiler directly.

Cargo is a fantastic tool, easily one of the best of its ilk, but real talk: it needs to be normalized that sometimes you don't want or need to use it. It is fit to a very specific set of tasks (mostly producing stand-alone binaries), and that set of tasks is a subset of the tasks rust as a whole is fit for.

Re: Ruby YJIT Ported to Rust

#78

Earlier quoted context omitted.

A Ruby program can delete all of the files on a computer, insert arbitrary rows into a database, drop a table, send email with attachments, etc. Am I correct that you're concerned the Ruby JIT itself will have a security vulnerability in the act of JIT compiling Ruby code? This seems extremely myopic.

JS engines have had many serious vulnerabilities in their JIT optimizers, it’s not myopic at all and is a well known technique in the industry. I agree that some folks aren’t executing untrusted ruby code so they wouldn’t have to worry about this - but how many PaaS/SaaS products out there are? Or how about third party dev tools that are blindly downloaded and executed on local workstations or CI pipelines?

> JS engines have had many serious vulnerabilities in their JIT optimizers, it’s not myopic at all and is a well known technique in the industry.

HotSpot and V8 are both written in C++ and get more use than any other JIT on Earth.

Can you provide a link to a CVE caused by JIT miscompilation and explain how Rust would have been able to prevent the bug in a way that C++ wouldn't?

> I agree that some folks aren’t executing untrusted ruby code so they wouldn’t have to worry about this - but how many PaaS/SaaS products out there are?

This is what Xen, KVM, and Hyper-V do.

> Or how about third party dev tools that are blindly downloaded and executed on local workstations or CI pipelines?

Are you suggesting a Ruby JIT shouldn't generate machine code that corresponds to the Ruby program, but somehow magically prevent stupid developers from doing stupid things?

Re: Ruby YJIT Ported to Rust

#79
post #33

I found this part odd > . If YJIT is built in dev mode, then cargo is used to fetch development dependencies, but when building in release, cargo is not required, only rustc I'm not finding any information on why they bypass cargo and build directly with rustc. I'm curious what requirements led to this.

Cargo is .. not a pleasant build tool to integrate into other build systems. If you have a project (like mainline ruby) where the dominant mode is C and you need to integrate some rust into it, you will eventually feel like it'd be a useful use of your time to bypass cargo and use the compiler directly. Cargo is a fantastic tool, easily one of the best of its ilk, but real talk: it needs to be normalized that sometim…

Hilariously, years ago I did some Rust/Ruby integration, for fun, and had Ruby’s makefiles just call Cargo to build the rust code. It worked just fine.

It doesn’t work for all things in all cases, of course, but it can be workable. At work we built a build system on top of Cargo to paper over some of its deficiencies. It’s not ideal but IMHO it’s still better than dealing with rustc directly. In this case it’s easier for them since they have no external dependencies.

Re: Ruby YJIT Ported to Rust

#80

Earlier quoted context omitted.

Cargo is .. not a pleasant build tool to integrate into other build systems. If you have a project (like mainline ruby) where the dominant mode is C and you need to integrate some rust into it, you will eventually feel like it'd be a useful use of your time to bypass cargo and use the compiler directly. Cargo is a fantastic tool, easily one of the best of its ilk, but real talk: it needs to be normalized that sometim…

Hilariously, years ago I did some Rust/Ruby integration, for fun, and had Ruby’s makefiles just call Cargo to build the rust code. It worked just fine. It doesn’t work for all things in all cases, of course, but it can be workable. At work we built a build system on top of Cargo to paper over some of its deficiencies. It’s not ideal but IMHO it’s still better than dealing with rustc directly. In this case it’s easier…

I mean, calling rustc isn't so bad other than managing dependencies. I don't think it's really all that much more fraught than the compilers of other complex languages (including C++) that people manage to interact with directly. But cargo is simultaneously so good at dealing with dependencies, and (for lack of a better word) parasitic in its integration with nearly every crate in existence, that the moment you want to pull something else in it gets Hard.

Where it gets real messy is if you want to go back and forth (C->rust->C or rust->C->rust where the bookends are in the same codebase). This was a thing we wanted to do at the job I just left, but we never managed to make it work in a way that wasn't very janky. This was in a very mature and large C codebase managed by cmake, where we were gradually eating parts of it with rust, though.

Post reply on HN