Hacker News new | ask | show | jobs
by freikev 4639 days ago
Can you expand on what you mean by "confusing x86/x64 message"? I'd love to help clear it up. Are you saying that people will believe that the reason the JIT is so much faster is because it's 64 bits? That's the exact opposite of reality: 64 bit programs tend to be slower, because they have to manipulate more data (all pointers take twice as much space, the Win64 ABI requires a minimum of 48 bytes of stack per non-leaf function, etc...)
2 comments

Do all 64-bit programs tend to be slower all the time though? I'd think it would be faster because you're processing more data per clock cycle. Or is that the x64 JIT hasn't been optimized to take advantage of the latest gen of 64-bit processors (I heard stuff about not making use of the latest Math.Pow a while ago)?
Programs that are pointer-heavy tend to be a little slower. There's really not that much 64-bit arithmetic going on in the average application, so the more data per clock cycle only helps in a particular class of apps. Cryptography tends to do significantly better, for that exact reason. You do seem to be conflating code quality with compiler throughput, though. I'll try to clarify in much more detail in a CLR Codegen blog post soon.
> I'd think it would be faster because you're processing more data per clock cycle.

This is only true if you happen to be dealing with integers larger than 32 bits (rarely in most of today's code). The real performance benefit of x64 has more to do with a larger number of general-purpose registers. More registers allow (but don't guarantee) programs to spend less time accessing main memory, thus gaining some speed.

Yes, I knew about the registers. I guess I overestimated the number of applications that involve large number computations.
Or perhaps I underestimated them...
Why can't the CLR come up with their own "X32" target? IIRC, they made the default for projects in VS to be 32-bit explicitly because of better codegen and lower overhead. If an app is OK with 4GB of RAM, why not let the process run in 64-bit mode, but use 32-bit pointers?

Also, why should the Win64 ABI constrain everything? Certainly it'd only be needed around the edges, but for .NET code calling other .NET code, you're free to do interesting things. (Like pass a GUID or tuple in a single register if it'd help.)

Keep in mind that Windows emphasizes a unified ABI on AMD64 largely because of what happened on x86. The x86 ABI sort of evolved into this "wild west" kind of situation, with various calling conventions for different languages/runtimes and usage scenarios (i.e. stdcall, cdecl, fastcall, pascal, etc.), which ends up making things unnecessarily complicated for the OS. (Kevin has an old blog post where he discusses this in more depth: http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling...)

Being a good OS citizen and sticking to the Win64 ABI also makes some things significantly simpler for the rest of the runtime. An obvious example of where this pays off is native interop (e.g. P/Invoke, COM interop, C++/CLI), but one less obvious example of where this comes into play is actually managed exception handling (which is built on top of the underlying Structured Exception Handling mechanism that Windows provides). Not only does adhering to the unified ABI allow managed exceptions to interop with native exceptions, but it also makes things simpler for debuggers, anything that needs to walk the stack, etc.

Remember, the CLR is really more of an execution engine, and not so much a "virtual machine". We try not to disrupt the architectural conventions of the underlying platform, since we're not trying replace the OS environment itself.

--Henry Baba-Weiss [MSFT]