4 ms·
I'd be interested in seeing how much of this advice applies to architectures other than x86. As a side note, definitely don't follow the advice about using pos
by yalue 12y ago
I'd be interested in seeing how much of this advice applies to architectures other than x86.
As a side note, definitely don't follow the advice about using position-dependent code unless you are working in a very performance-intensive and isolated environment. Just a single non-relocatable module/dll completely undermines the benefits of ASLR, so an attacker with a copy of your program will have a much easier time crafting an attack against it.
- maximilianburke 12y agoA lot of it generally holds true if you're programming for x86/x64, ARM, or PowerPC. The "hierarchy of speed" could use some updating, I think these days it is more along the lines of: 1. Comparisons (no branch, just compare) 2. u/int add/subtract/bit operations 3. FP mul 4. FP add/sub 5. FP div 6. u/int mul 7. indexed array access (data in L1, including latency for data to move to registers) 8. u/int div That rough order seems to generally hold on a modern Haswell processor or the in-order PowerPC cores in an Xbox 360, though the cycle counts will vary. Being thoughtful with respect how you access your data, paying attention to the effects of access patterns on caching, will almost always help regardless of the target architecture :)
- nkurz 12y ago1. Comparisons (no branch, just compare) 2. u/int add/subtract/bit operations Is there a reason you follow Andrei's lead and suggest that comparisons operations are faster than integer subtraction? At least for x64 on Intel, I think they would always be the same speed and thus should be grouped together. Are they different on the other platforms?
- mattgodbolt 12y agoThe only justification I can think of for that statement is that on modern processors (Sandy Bridge and above), micro-op fusion in the decode stage can fuse a comparison with a branch that immediately follows it, turning it into a "compare and branch" micro-op.
- spc476 12y agoOne possibility: the compare only updates one register (flags), not two (flags and the destination register).
- optymizer 12y agoI didn't really get the benefits of not using PIC. My understanding is that, at compile time, the compiler will generate relative branches rather than absolute jumps, which is stored as an immediate in the instruction. Is it different for x86? Where's the speed advantage coming from?
- gsg 12y agoIt's not relative vs absolute, no. Jumps and call instructions have been using PC-relative values right from the start. You might be thinking of RIP-relative addressing, which is useful in PIC to access globals. The problem is that there is no way to know at compile time the position of an instruction relative to its target. Non-PI code handles this by having the linker update the relevant constants in the machine code. PI code has to function without modification, so it must indirect through a global table. It's this indirection that causes the speed hit. On the other hand, PI code benefits from the ability to share code pages, so it can be faster in some circumstances.