6 ms·
Could you name a JIT compiler that doesn't do this kind of thing, yet offers performance comparable to AOT-compiled languages? (FWIW, I'm not saying it's impos
by catnaroek 10y ago
Could you name a JIT compiler that doesn't do this kind of thing, yet offers performance comparable to AOT-compiled languages?
(FWIW, I'm not saying it's impossible. It's perfectly possible, but you'd need a source language that offers much better static guarantees than the typical language that a JIT compiler is written for.)
---
Sorry, can't reply to you directly, because “I'm submitting too fast”. So my reply goes here:
> for the simple reason that type systems cannot capture all relevant runtime context.
Type checking isn't the only kind of static analysis out there. And there's no need to use statistics to optimize anything at runtime when your ahead-of-time compilation step already emits optimal target machine code.
> Java is a good example here, since it's strongly statically typed.
Java is as dynamically typed as it gets: `instanceof`, downcasts and reflection, all conspire to reduce the usefulness of static type information to zero.
> By your reckoning, all greedy optimizations that CPUs do like branch prediction and prefetching are also similarly 'inelegant', because they can be wrong and require rolling back.
Yes, indeed. It's more elegant to know beforehand what exactly you have to do, and then do just that and nothing else.
- smallnamespace 10y ago> that _doesn't_ do this kind of thing Why does that matter to anyone? > you'd need a source language that offers much better static guarantees than the typical language that a JIT compiler is written for Java and C# are both statically, strongly typed languages where JITs are the dominant implementation. Almost by definition, it's impossible to write a JIT compiler that outperforms AOT compilation without looking at runtime data, because AOT compilers have a lot more time to look for difficult static optimizations. The reason JITs can keep up is because they have access to information that an AOT compiler does not. > And there's no need to use statistics to optimize anything at runtime when your ahead-of-time compilation step already emits optimal target machine code. This is simply untrue. For example, it's not possible to statically determine whether a function should be inlined or not. However, a JIT can see that it's used in a hot loop and dynamically inline. For any language, no matter the type system, runtime information will always be a superset of compile-time information. There will always exist optimizations in a JIT that aren't possible in an AOT compiler. > Java is as dynamically typed as it gets: `instanceof`, downcasts and reflection, all conspire to reduce the usefulness of static type information to zero. Idiomatic Java code doesn't use these features heavily. Just because it's possible to wipe out type information doesn't mean that the vast majority of code that an AOT or JIT compiler sees won't be strongly typed.
- catnaroek 10y ago> For example, it's not possible to statically determine whether a function should be inlined or not. MLton has absolutely no problems inlining functions, even higher-order functions, at compile time. This is only difficult in languages with virtual methods, because they can be overridden anywhere. If anything, that's an indictment of virtual methods, not AOT compilers. > However, a JIT can see that it's used in a hot loop and dynamically inline. What if it's a virtual method call that's known to be overridden in several places? You can't inline it, even if it's in the middle of a hot loop. > For any language, no matter the type system, runtime information will always be a superset of compile-time information. Runtime information is always anecdotal, specific to one particular run of a program, so... > There will always exist optimizations in a JIT that aren't possible in an AOT compiler. ... for every “optimization” a JIT can perform, there will always exist a program for which the “optimization” will have to be rolled back after it has already been performed, because it turned out to be unsound. > Idiomatic Java code doesn't use these features heavily. Language implementations must work correctly whether you write idiomatic or unidiomatic code. > Just because it's possible to wipe out type information doesn't mean that the vast majority of code that an AOT or JIT compiler sees won't be strongly typed. Most code I write in Python could be given static types too. That doesn't make Python a statically typed language. And “strongly typed” doesn't really mean anything.
- smallnamespace 10y ago> MLton has absolutely no problems inlining functions, even higher-order functions, at compile time Of course, but how does it know which functions to inline? If you inline everything, then you will blow through your cache. > What if it's a virtual method call that's known to be overridden in several places? You can't inline it, even if it's in the middle of a hot loop. That's not true--a JIT could optimistically replace with a concrete realization. > Runtime information is always anecdotal, specific to one particular run of a program, so... That's a benefit. No matter what AOT compiled code you have, it is possible to speed up execution if you know what code paths you will take. > ... for every “optimization” a JIT can perform, there will always exist a program for which the “optimization” will have to be rolled back after it has already been performed, because it turned out to be unsound. Yes, but so what? As long as it improves performance in the average case, and the worst case is bounded, then that is a net win. You can equally well write deliberately obfuscated code that an AOT compiler has trouble with. > Language implementations must work correctly whether you write idiomatic or unidiomatic code. Implementation is correct. Only reflection is slow. If you don't want that, don't write reflection.