3 ms·
The article mentions > This fact is sometimes useful; compilers can use redundant prefixes to pad a single instruction to a desirable alignment boundary. so I
by lights0123 3y ago
The article mentions
> This fact is sometimes useful; compilers can use redundant prefixes to pad a single instruction to a desirable alignment boundary.
so I imagine that could happen under the right optimization mode.
- ithkuil 3y agoWhy would a compiler prefer a redundant prefix over a nop for alignment?
- Vecr 3y agoIt can be faster (at runtime).
- ithkuil 3y agoso basically you're saying that the cpu frontend missed the opportunity to ignore the 0x90 because it was an actual instruction which would be converted into an actual nop uop? Is this still the case or modern intel CPUs optimize out the nop in the frontend decoder?
- Vecr 3y agoSome compiler writers thought that was the case, if [0] is related to OP. I don't have a "modern" (after 6th gen) Intel CPU to test it on, but note that most programs are compiled for a relatively generic CPU. [0]: https://github.com/microsoft/mimalloc/issues/807 https://github.com/microsoft/mimalloc/issues/807
- rasz 3y agotedunangst down in the comments linked https://repzret.org/p/repzret/ https://repzret.org/p/repzret/ : "Looking in the old AMD optimisation guide for the then-current K8 processor microarchitecture (the first implementation of 64bit x86!), there is effectively mention of a “Two-Byte Near-Return ret Instruction”. The text goes on to explain in advice 6.2 that “A two-byte ret has a rep instruction inserted before the ret, which produces the functional equivalent of the single-byte near-return ret instruction”. It says that this form is preferred to the simple ret either when it is the target of any kind of branch, conditional (jne/je/...) or unconditional (jmp/call/...), or when it directly follows a conditional branch. Basically, when the next instruction after a branch is a ret, whether the branch was taken or not, it should have a rep prefix. Why? Because “The processor is unable to apply a branch prediction to the single-byte near-return form (opcode C3h) of the ret instruction.” Thus, “Use of a two-byte near-return can improve performance”, because it is not affected by this shortcoming." ... " If a ret is at an odd offset and follows another branch, they will share a branch selector and will therefore be mispredicted (only when the branch was taken at least once, else it would not take up any branch indicator %2B selector). Otherwise, if it is the target of a branch, and if it is at an even offset but not 16-byte aligned, as all branch indicators are at odd offsets except at byte 0, it will have no branch indicator, thus no branch selector, and will be mispredicted. Looking back at the gcc mailing list message introducing repz ret, we understand that previously, gcc generated: nop, ret But decoding two instructions is more expensive than the equivalent repz ret. The optimization guide for the following AMD CPU generation, the K10, has an interesting modification in the advice 6.2: instead of the two byte repz ret, the three-byte ret 0 is recommended Continuing in the following generation of AMD CPUs, Bulldozer, we see that any advice regarding ret has disappeared from the optimization guide." TLDR: Blame AMD K8! First x64 CPU. This GCC optimization is outdated and should only be used when specifically optimizing for K8.