3 ms·
Presumably, Apple is relying on SSE for floating point, like x86-64 does. That certainly is both faster and simpler than dealing with the bizarre x87. And you
by ssp 17y ago
Presumably, Apple is relying on SSE for floating point, like x86-64 does. That certainly is both faster and simpler than dealing with the bizarre x87.
And you don't have to insert extra code at all call sites. You can assume that your stack is correctly aligned at entry too, so if you just make your stack frame a multiple of 16 bytes, you'll be fine.
- barrkel 17y agoThe amount of code that uses floating point is a rounding error, pardon the pun. And generating RPN instructions really is easier than a register architecture - RPN is just a post-order traversal of the expression tree. Targeting a register architecture requires you to allocate the registers yourself. You're also assuming that there is no intra-procedural stack modification that may be in effect while a function is being called.
- deleted 17y ago[deleted]
- jedbrown 17y agoMost compilers produce exclusively SSE instructions for floating point these days (unless you're explicitly generating code for machines that don't support it). But the stack doesn't need to be aligned at the call site for this, it can be done in the preamble of whatever function uses it (it costs one BAND instruction). The stack is not aligned at function entry because the CALL instruction pushes the address on the stack, thus having alignment at the call site forces the stack to be unaligned at function entry, however, it is unaligned by a known amount so you can produce aligned addresses by subtracting a constant value (skipping the BAND instruction). The featured rant misses this point, you get aligned addresses just as easily at the bottom of your frame as at the top.
- ssp 17y agoRight, "just make your stack frame a multiple of 16 bytes" was wrong; I should have said "just make your stack frame 16 * k - 4 bytes long". This is basically free because the size of the stack frame is known at compile time. Realigning the stack at runtime though, is expensive and complicated.
- jedbrown 17y agoAligning the stack at runtime is one instruction in the preamble so it's not a big deal, especially if the function is big enough to have non-register SSE locals. Also, when using VLAs, it's not optional. I use SSE all the time and have no problems with the alignment requirements, but it's not really a performance issue and I'm doubtful that it was worth the time for people to learn and deal with this idiosyncrasy.
- jedbrown 17y agoActually, come to think of it, when the function doesn't call anything else, locals will be indexed off the base pointer and the stack pointer will not be explicitly moved. So it costs two extra instructions to get aligned locals in a function that needs non-register locals but doesn't call any other functions. Of course these are 1/.33 (latency/inverse throughput) instructions.
- ssp 17y agoYou need to restore the stack to what it was before on return. Normally you can easily do that because you know the stack pointer delta at compile time. But when realigning at runtime, you don't, so you need to compute the difference and then store that somewhere, and on return you have to read that back and add it to the stack pointer. Or is there some trick that I'm missing?
- jedbrown 17y agoIt's in the frame pointer. Edit: You're right, optimized code might not save the frame pointer and this wouldn't provide any benefit if your frame had unknown size. But usually the preamble saves the old ESP in EBP and it is restored at the end. Maybe there is another alternative.
- ssp 17y agoHmm, I was actually about to edit my comment to say that you are right because usually you'll store the old stack pointer as the new base pointer. I guess the answer is that realigning at runtime costs a register, but most code has to pay that cost anyway.