4 ms·
This project is trying to do too many things. It seems like Ruby needs a profile guided optimizer, which means building an IR that is suitable for profile-guid
by pizlonator 7y ago
This project is trying to do too many things.
It seems like Ruby needs a profile guided optimizer, which means building an IR that is suitable for profile-guided optimization. That’s way different from classic IRs like this since it means having provisions for OSR exit.
I recommend looking at these slides to learn how to do it.
http://www.filpizlo.com/slides/pizlo-speculation-in-jsc-slides.pdf http://www.filpizlo.com/slides/pizlo-speculation-in-jsc-slid...
http://www.filpizlo.com/slides/pizlo-splash2018-jsc-compiler-slides.pdf http://www.filpizlo.com/slides/pizlo-splash2018-jsc-compiler...
- chrisseaton 7y agoI agree - I think MIR is trying to produce better machine code more quickly, but that isn't the problem Ruby faces! The problem Ruby faces is having to inline through ten levels of metaprogramming in order to get any meaningfully-sized compilation unit that you can optimise, and only then it makes sense to worry about code generation. However, the reason that this is not so simple is that Ruby is a vastly more complicated language than JavaScript (I've worked on implementing both.) Ruby has an enormous standard library and most Ruby programs are just endless calls to the that library, so your compiler must be able to understand the library semantically, either by rewriting it in Ruby (not likely at scale in MRI) or by adding tens of thousands of individually optimised intrinsics (again not likely). Ruby is digging itself further into a local optima with these approaches optimisations, rather than looking further around for a better global optima.
- pizlonator 7y agoYour description of optimizing Ruby sounds like it is exactly like optimizing JS. JSC’s main optimizing IR (the DFG) is all about understanding the standard library semantically. We write the standard library in JS+hacks (called “builtins”) or C++ (pick on a per function basis). Some of those functions have opcodes in DFG, or are built out of primitives that have their own specialized opcodes in DFG. Maybe the reason why Ruby optimization has problems is nobody has done it the JSC way.
- chrisseaton 7y ago> Your description of optimizing Ruby sounds like it is exactly like optimizing JS. Yes it's the same problem and it's unique to neither Ruby nor JS - but the problem is just scale. Ruby has a larger library, so needs more rewritten from the current C into Ruby+builtins. And then that rewrite doesn't maintain Ruby semantics (the C API currently used does not exactly match Ruby semantics) so a rewrite matching semantics is often very hard. > Maybe the reason why Ruby optimization has problems is nobody has done it the JSC way. People have been trying the approach you use in Core (for over a decade, starting with Rubinius, now TruffleRuby and others), but I think (based on practical experience working on optimising both languages) that it's just a larger problem in Ruby which is why it hasn't been conquered yet.
- pizlonator 7y agoI think that the way you’re describing the solution for Ruby tells me that you don’t see the problem the way that I see it. The problem isn’t rewriting things in builtins. The problem is making an IR in which you can reason about the standard library at scale: reason about its speculation opportunities, all of the implied dependencies and effects, it’s GC impacts, etc. None of the IRs I’ve seen people try for Ruby does that. JSC’s DFG IR does a lot of this. Hence I don’t think folks have really tried the JSC approach for Ruby.
- chrisseaton 7y agoDo you not think the Truffle and Graal IRs do this?
- pizlonator 7y agoNo, they don’t do this. They try to infer specialization from an AST interpreter. That’s not on the same planet as what I’m talking about.
- chrisseaton 7y ago
- HALtheWise 7y agoIt looks like Mir's approach to this is to build a jit compiler that has access to the C source of the standard library and can inline it into the JITted code of Ruby functions, and vice versa. Building a compiler that can handle mixed-language input might be easier than rewriting the standard Library to all be in one language.
- jashmatthews 7y ago"inlining everything" is actually maybe not the best approach. It's been talked about a lot, but it's not always helpful. For example, C compilers (or LLVM) are unable to optimize boxing and then unboxing a double into a Ruby Flonum and back.
- pizlonator 7y agoExactly. You need a compiler that can reason about Ruby semantics. Llvm can’t. Not sure MIR will do any better. The key is: - large opcode set and an architecture that tries to amortize the pain of lots of opcodes. - excellent support for speculation and effects analysis.
- beagle3 7y agoAnd maybe it is. GP, chrisseaton did that in Truffle/Graal and its the fastest ruby there is.
- tomcam 7y agoI don’t think CockroachJIT is taken... (for the uninitiated, I kid. Sample of previous naming controversy at https://news.ycombinator.com/item?id=14309903 https://news.ycombinator.com/item?id=14309903)