Hacker News new | ask | show | jobs
by maxime_cb 1205 days ago
> With all due respect, you ain’t going to beat the JVM with your UVM’s JIT compiler, not even close.

I think I may be able to get very close to native performance. I don't want to sound like an asshole by appealing to authority, but you aren't talking to a teenager writing an interpreter from their parent's basement. I have 21 years of programming experience, a PhD in compiler design and multiple published papers. I have some idea what I'm talking about.

> Why do you think creating a similarly good JIT compiler to a very similar design would be any easier in case of UVM?

The design is superficially similar to the JVM but it's also quite different. UVM's bytecode is untyped. It maps fairly directly to the x86-64 and ARMv8 instruction sets. If you want an idea of how a simple JIT compiler for a bytecode like that can perform, you should look at the performance of Apple's Rosetta. But, I actually think I can build something that yields better performance than that :)

2 comments

You say this stuff is incredibly hard. Kaba says it's impossible and don't try. I say it's easy. I whipped up a JIT to make my virtual machine go 50x faster. I never expected Blinkenlights to go faster than Bochs. Now all the sudden it's outperforming Qemu for many of my use cases. People are doing stuff with it I never expected, like booting the Linux Kernel and running Alpine Linux on Cygwin. Garbage Collection is easy too. I wrote a GC using the NSA POPCNT instruction for an experimental LISP dialect I wrote last Winter called Plinko. It ran faster than any other LISP interpreter I've seen, as measured by the GC-intensive binary trees benchmark game. The only thing faster was SBCL with JIT which was only a hair faster than Plinko using just an interpreter. NIH is awesome because the truth is, when you're focused on your own needs, outperforming the big official things is like shooting fish in a barrel. Technologies like the JVM aren't great because they're better. They're great because they've carefully crafted the long tail of edge cases and compromises that enables it to be good enough for the largest group of people. Generalized software is at a huge disadvantage because bloat fills caches and it can't use special case algorithms. For example, people publish papers all the time bragging about how they beat the performance of the C++ STL at some given thing and that impresses the people who never tried, but it honestly isn't that hard if you consider the burdens that the STL is required to carry.
I eagerly await your results, and didn’t want to sound condescending at all, sorry if it came across like that. I was just genuinely interested in a - to me - more understandable difference.

Also, what does “native performance” even mean here? Only removing the interpreter overhead?

Thanks for clarifying. Tone is sometimes ambiguous via text.

At the moment I'm in no rush to actually write the JIT compiler because I think it's faster to iterate with an interpreter. I want to flesh out the VM and its APIs, test the hell out of everything and develop the system a bit more first.

The interpreter runs at something ~400 million instructions per second on my laptop, which is probably close to the performance of an old school Pentium 2 chip, so it's actually fast enough to run a lot of non-trivial software. With even a really basic JIT I should be able to hit 10x that throughput. I've benchmarked code out of GCC and it runs about 27 times faster (on a microbenchmark).