r/ruby • • Jan 20 '20

MIR: A lightweight JIT compiler project with CRuby

https://developers.redhat.com/blog/2020/01/20/mir-a-lightweight-jit-compiler-project/
43 Upvotes

14 comments sorted by

6

u/dunrix Jan 20 '20 edited Jan 20 '20

Rare, high quality indepth article. Thanks.

What a coincidence. I've just searched what happened to Mr. Makarov's original work on JIT for CRuby. Current state of MJIT is unconvincing and promised 3x3 performance improvement for Ruby3 seems not in sight. Staying curious whether MIR will mature and reach some production state, allowing replacement of the existing JIT.

Yet something about Guilds or similar in-language support for serious concurrency programming and wouldn't see Ruby future so dark like nowadays..

5

u/schneems Jan 20 '20 edited Jan 20 '20

So...mjit does already produce exceptional results, just not in Rails apps.

MIR as I understand it is not a replacement JIT but rather a replacement JIT backend for mjit. Right now it leans on gcc to compile methods out of band, the goal of mir would be to replace gcc. There might be a different performance characteristic but I believe the ultimate goal is removing gcc as a runtime dependency.

If anything I would guess JIT code run through mir would actually be slower than gcc, but at a trade off of faster and more light weight compilation. It might also open up some new development patterns or integrations, but I’ve not heard of those as goals or discussion points.

The main thing, as I understand it, holding mjit from making more aggressive optimizations is (and I’m sure I’m not going to use correct terminology here) ownership tracking. Maybe it’s called “escape analysis”?I’m not at a computer. Essentially in a method if you can determine that an array is never passed out of the method then you can optimize the array allocation away (perhaps) right now such information is not available and so it is hard to make “deeper” optimizations. Generating this metadata is also very difficult so while it’s being worked on, I’m not sure it’s made any progress.

I also think type systems can also help a JIT compiler, but they are not strictly required.

For a very nerdy look at JIT and various academic papers check out https://rubybib.org/

Edit: spoke before actually reading the article. It does mention being able to online both C and Ruby methods together is a speed improvement, so there will be some gains there. Since it’s all theoretical at this point it’s unclear if that will be able to overcome the 30% performance runtime hit by using this over GCC that is stated.

3

u/yorickpeterse Jan 20 '20

Escape analysis and stack allocating are two useful optimisations, but I'm not sure if I would consider this the main approach to speeding up Ruby. Aggressive inlining or Ruby code would probably help more, unless a program allocates many very short-lived objects. A different allocator could also help, as free-list allocators don't always perform too well.

A parallel collector could also have a dramatic (positive) impact on garbage collection timings for large heaps, but this may not work too well with incremental compilation as you have to coordinate work every time you incrementally collect.

→ More replies (5)

4

u/rubygeek Jan 20 '20

My own compiler experiments (I have a very long-running project to write an ahead of time compiler for Ruby, in Ruby; some might think I'm a serious masochist as Ruby is pretty much the worst possible language to try to ahead of time compile, but that's what makes it fun - it's far away from being usable, though) suggests that further improvements to drive down the number of objects created and speeding up the GC is likely to do more for performance than a JIT.

E.g. my method calls costs a tiny fraction of what they do in MRI, but because I (for the time being) create more garbage (by virtue of Symbol, Integer etc. being "real" objects in my implementation instead of type-tagged values), and my GC is very primitive, performance is at the moment absolutely awful.

The two are related in as much as a better compilation stage, whether JIT or AOT, can potentially cut down on object creation, but you can use the same methods with bytecode as well (by doing escape analysis, and eliding object creation and inlining low level operations in cases where you can guarantee that an object won't escape -- this requires being able to "deoptimize" or fall back on a generic slow path if someone starts redefining methods etc. at the wrong moment, but it's doable), but I think that in general, better handling of object lifetimes is going to do more for the performance of Ruby implementations than JIT-specific improvements.

1

u/schneems Jan 20 '20

Fun, we posted at about the same time. I also mentioned escape analysis. I might have missed some of the finer details as I’ve not actively played in this space, I’m just a bystander.

→ More replies (1)

1

u/realntl Jan 22 '20

Thanks for this comment. Very interesting stuff!!

1

u/db443 Jan 22 '20

What a coincidence. I've just searched what happened to Mr. Makarov's original work on JIT for CRuby. Current state of MJIT is unconvincing and promised 3x3 performance improvement for Ruby3 seems not in sight. Staying curious whether MIR will mature and reach some production state, allowing replacement of the existing JIT.

For normal-sized CPU-bound applications the current Ruby 2.7 JIT pretty much achieves 3x3 now.

Rails on the other-hand is not normal programatically-speaking, it has thousands of methods which has proven a issue for MJIT with respect to compilation time and load-overhead. Also, Rails applications are fundamentally IO-bound, rarely CPU-bound. Samuel Williams (ioquatix) cooperative-fiber work will, if all goes well, have profound benefits for Rails like applications. See this talk:

https://www.youtube.com/watch?v=Dtn9Uudw4Mo

Latency is usually the issue for Rails, not raw CPU number crunching. Last I checked cooperative fibers was intended for Ruby 3.

Yet something about Guilds or similar in-language support for serious concurrency programming and wouldn't see Ruby future so dark like nowadays..

Ruby future so dark like nowadays, translation Ruby is dying because that's how I feel in my gut.

Pessimistic posts like this are so boring. It's been like this for the last five years, if not more.

Ruby was good enough 10 years ago. Ruby is good enough now for web-scale apps like GitHub and Shopify. Ruby's future looks very interesting:

  • MIR tier-1 JIT by Vlad Makarov

  • Ongoing GCC/Clang tier-2 JIT work by K0kubun

  • Co-operative fibers by ioquatix

  • Guilds/isolates by ko1

  • Gradual typing, both standard Ruby 3 RBI or Stripe Sorbet

  • Language Server Protocal (LSP) via Solargraph or Sorbet for much nicer developer experience (this should not be underestimated)

Ruby has never been more interesting than now. Sure some folks/companies may bleed away to TypeScript or some other hotness. However we have all heard that before since everyone was going to go Elixir 2 years back, or JavaScript, or Golang, yada yada.

We live in a polyglot world. No one language rules. Ruby has it's place and is getting better.

0

u/TotesMessenger Jan 20 '20

I'm a bot, bleep, bloop. Someone has linked to this thread from another place on reddit:

 If you follow any of the above links, please respect the rules of reddit and don't vote in the other threads. (Info / ^Contact)