Yay! I'm so excited to use the `async` methods in production with MySQL. The biggest bottleneck for our PHP apps can now have a workaround in some cases, that's brilliant.
> Integration of LLVM as a further optimization step to make the hottest code run even faster on HHVM.
These multistage JITs are absolutely fascinating, I believe Safari is doing something similar with Javascript. Intuitively I would've assumed the overhead of firing up yet another JIT and VM to run it on would make it not worth it, but I guess the instructions currently generated are so far off optimal that it is worth doing.
EDIT: Anyone know of any papers regarding multi-stage JITs that I can check out?
The async support you linked, while useful, isn't really the same thing. It requires explicit, manual coordination between different parts of the code that want to fetch data. You're responsible yourself for batching fetches, polling, and running other code until the results are returned.
With Hack's async support, the runtime manages all of this for you. You call "await $query", and then your function is suspended until the data is available. Other code automatically runs until it too hits an await statement -- which might block it on MySQL, memcache, curl, or anything else, with no extra manual coordination needed. The runtime manages it all for you.
http://hhvm.com/blog/7091/async-cooperative-multitasking-for... has some examples for what this looks like with curl -- in the final example, notice how you can just "await" on a bunch of different things and let the runtime worry about coordinating all of them.
The async stuff in HHVM is far more powerful than the meagre-at-best support for asynchronous operations in the original PHP runtime. In usage, HHVM's will be much more powerful.
LLVM isn't really a VM, it's just a compiler toolkit. And really, the overhead of converting your data structure to LLVM IR is almost certainly trivial compared with the cost of the optimizations it is performing.
LLVM IR is definitionally coding to a virtual machine. It doesn't bear a ton of similarity to the underlying architecture in most cases. gcc's GIMPLE is the same idea. (That it's compiled down to machine code doesn't make what you're working with not-a-virtual-machine.)
Heh, I originally wrote something more pedantic then edited it down. It's definitely a virtual machine insofar as its an abstract computational machine, but it's not in the probably more common definition of "an interpreter, possibly with a JITing compiler on the side, for an abstract computational machine" (though LLVM does have an interpreter, it's not really ever intended to be used for anything).
Multi-stage JITs are indeed fascinating and give some nice wins, but as a "user" (that is, a developer) I find them frustrating at times because they make it more difficult to reason about the performance and behaviour of my code.
Not only a priori, but in terms of testing actual code and designing benchmarks as well - you have to make sure the right sections of code are hot, hitting the right levels, etc. It's extra mental load and work. (and if you're a JS developer, you may have to do this across multiple platforms). And oh, regressions and updates.
I'm not entirely convinced it's all worth it, but so far I'm begrudgingly accepting it.
Sure, but with most AOT compliers you only get one machine-code version of your code, which is easier to benchmark than worrying about the multiple levels of a JIT.
Comments
Yay! I'm so excited to use the `async` methods in production with MySQL. The biggest bottleneck for our PHP apps can now have a workaround in some cases, that's brilliant.
> Integration of LLVM as a further optimization step to make the hottest code run even faster on HHVM.
These multistage JITs are absolutely fascinating, I believe Safari is doing something similar with Javascript. Intuitively I would've assumed the overhead of firing up yet another JIT and VM to run it on would make it not worth it, but I guess the instructions currently generated are so far off optimal that it is worth doing.
EDIT: Anyone know of any papers regarding multi-stage JITs that I can check out?
Async MySQL queries have been available to you in PHP since PHP 5.3.0 released in 2009:
If that has been your bottleneck, why haven't you been using them?The async support you linked, while useful, isn't really the same thing. It requires explicit, manual coordination between different parts of the code that want to fetch data. You're responsible yourself for batching fetches, polling, and running other code until the results are returned.
With Hack's async support, the runtime manages all of this for you. You call "await $query", and then your function is suspended until the data is available. Other code automatically runs until it too hits an await statement -- which might block it on MySQL, memcache, curl, or anything else, with no extra manual coordination needed. The runtime manages it all for you.
http://hhvm.com/blog/7091/async-cooperative-multitasking-for... has some examples for what this looks like with curl -- in the final example, notice how you can just "await" on a bunch of different things and let the runtime worry about coordinating all of them.
^^^ What he said :)
The async stuff in HHVM is far more powerful than the meagre-at-best support for asynchronous operations in the original PHP runtime. In usage, HHVM's will be much more powerful.
LLVM isn't really a VM, it's just a compiler toolkit. And really, the overhead of converting your data structure to LLVM IR is almost certainly trivial compared with the cost of the optimizations it is performing.
LLVM IR is definitionally coding to a virtual machine. It doesn't bear a ton of similarity to the underlying architecture in most cases. gcc's GIMPLE is the same idea. (That it's compiled down to machine code doesn't make what you're working with not-a-virtual-machine.)
Heh, I originally wrote something more pedantic then edited it down. It's definitely a virtual machine insofar as its an abstract computational machine, but it's not in the probably more common definition of "an interpreter, possibly with a JITing compiler on the side, for an abstract computational machine" (though LLVM does have an interpreter, it's not really ever intended to be used for anything).
Multi-stage JITs are indeed fascinating and give some nice wins, but as a "user" (that is, a developer) I find them frustrating at times because they make it more difficult to reason about the performance and behaviour of my code.
Not only a priori, but in terms of testing actual code and designing benchmarks as well - you have to make sure the right sections of code are hot, hitting the right levels, etc. It's extra mental load and work. (and if you're a JS developer, you may have to do this across multiple platforms). And oh, regressions and updates.
I'm not entirely convinced it's all worth it, but so far I'm begrudgingly accepting it.
It is no different than using multiple AOT compilers (for any standardized language) across multiple platforms.
Even the same compiler can behave differently just by changing the target CPU.
Sure, but with most AOT compliers you only get one machine-code version of your code, which is easier to benchmark than worrying about the multiple levels of a JIT.
Actually I think many developers aren't aware of the right tools for this type of job.
JITs are easy to benchmark when tools like Oracle Studio, Java Flight Recorder, dotTrace and so forth are used.
The problem is trying to benchmark them using old style concepts, e.g. outputting time differences to a text file.
Those tools don't exist for all JITed platforms. Hence the problem.
All the major javascript engines are multistage now, not just safari.
Though only Safari (well, JavaScriptCore) is using LLVM (as a fourth tier).