9 ms·
An optimization guide for assembly programmers and compiler makers (2018) [pdf]
- rolph 8y agoI like this site very much, its simple and old school. Take a tour around the site for some other aspects of agners work, there is a good treatise regarding the fundamentals of digital electronics, as well as a proposed archetecture standard [ForwardCom]. some [as in a couple] of the links on agners site are stale or dead but do give you the general idea what to look for. https://www.agner.org/digital/digital_electronics_agner_fog.pdf https://www.agner.org/digital/digital_electronics_agner_fog.... [PDF] and: https://forwardcom.info/ https://forwardcom.info/
- cpeterso 8y agoI'm interested in seeing how the section about "Future branch prediction methods" (page 17) will change in our post-Spectre world.
- monocasa 8y agoProbably not much. We'll probably just get speculative state barriers made full parts of the architectural specification.
- souprock 8y agoThis just came up today. Anybody know the answer? The problem involves a JIT (for opcodes, not scripting). Chunks of code are generated. Sometimes, a chunk will need to branch to a chunk that isn't yet generated or even allocated. Chunks can be cleared away for various reasons like evictions to make room, so the branches to a chunk might need to not go there anymore. One strategy is to use indirect branches. When the destination doesn't exist, the branch goes to code that will resolve that. It's a bit like how dynamic linkers work. Another strategy is to replace the code. The processor may stumble a bit over what is essentially self-modifying code, but then it eventually runs faster. The degree to which the processor will pause is a key consideration here. Anybody know? BTW, if you like digging into this stuff, we're hiring.
- jnordwick 8y agoCan't you place a trap where the target code would go? It would still be self-modifying code, but least you get rid of the indirection in the other way.
- souprock 8y agoNot only is that code not produced yet, but the memory isn't allocated yet. The location is thus unknown.
- muricula 8y agoAt the end of the first chunk just ret. When the second chunk is generated, also emit a thunk which calls the first chunk and then calls the second chunk. Should be quite nice and efficient and will leverage the return history buffer. You're right, this stuff is fun.
- muricula 8y agoAlso, self modifying code typically requires full pipeline serialization via an instruction like cpuid (x86) or isb (arm). There are comments about this in the architecture optimization manuals, but in general try not to go around munging code all the time. While I'm thinking about it, you should consider an out of proc JIT architecture like Edge has, as JITs are fragile and easily exploited [1]. [1]: http://wenke.gtisc.gatech.edu/papers/sdcg.pdf http://wenke.gtisc.gatech.edu/papers/sdcg.pdf
- souprock 8y agoOut-of-proc would be too slow to be worthwhile in this case. This JIT isn't doing a high-level language like javascript, where large blobs of code can be generated and the performance is limited anyway by calls into other things. This JIT is for machine instructions. It's something like valgrind or qemu, in which we run modern software.
- 8y ago
- CalChris 8y agoThere is also uops.info which has a different, more formal characterization of latency: https://arxiv.org/abs/1810.04610 https://arxiv.org/abs/1810.04610
- pedagand 8y agoAnd llvm-exegesis: https://llvm.org/docs/CommandGuide/llvm-exegesis.html https://llvm.org/docs/CommandGuide/llvm-exegesis.html "llvm-exegesis is a benchmarking tool that uses information available in LLVM to measure host machine instruction characteristics like latency, throughput, or port decomposition. Given an LLVM opcode name and a benchmarking mode, llvm-exegesis generates a code snippet that makes execution as serial (resp. as parallel) as possible so that we can measure the latency (resp. inverse throughput/uop decomposition) of the instruction. The code snippet is jitted and executed on the host subtarget. The time taken (resp. resource usage) is measured using hardware performance counters. The result is printed out as YAML to the standard output. The main goal of this tool is to automatically (in)validate the LLVM’s TableDef scheduling models. To that end, we also provide analysis of the results."
- anitil 8y agoSometimes I think I'm a 'full stack' developer, and then I read something like this. Sure I can dabble in simple assembly, but there's always a bigger fish.
- nickpsecurity 8y agoWell, that's pretty humble of you. :) I advocated for the term to only be used by folks that can build their own computer, language, OS, and apps. Look up Chuck Moore and Niklaus Wirth for examples focusing on simplicity. For full-stack architect w/ team building it, look up Bob Barton of Burrough B5000. I cant remember if early folks writing Lisp interpreters built the CPU's, too. I know Burger did for a Scheme CPU, though.
- hcs 8y agoNot quite down to the hardware level, but the VPRI STEPS project had that kind of thing in mind, see (PDF): http://www.vpri.org/pdf/tr2012001_steps.pdf http://www.vpri.org/pdf/tr2012001_steps.pdf The focus was on expressive power more than simplicity, though.
- CalChris 8y agoWell, remember what Carl Sagan said about full stack development: If you wish to make an apple pie from scratch, you must first invent the universe.
- the8472 8y agohttps://xkcd.com/1123/ https://xkcd.com/1123/
- heyjudy 8y agoHave you ever implemented optimized microcode for a pipelined, branch-predicting processor that you also had to build? MICMAC is the architecture we used once upon a time. I won all of the course's extra credit for both smallest microcode program and fastest (fewest micro ops) because I Huffman-encoded the macro ops of the test programs and used progressive decoding. How about a Java to MIPS compiler? In C++ and then again in Java just to be self-hosting. Or an all software OpenGL-compatible pipeline with painter-algorithm Z-buffering and trapezoid engine? Quaternions and all that state... fun-fun. Another mandatory project in college was a non-pre-fork()ed select() caching HTTP/1.0 proxy in POSIX C89. IPC was a PITA back then. There are still bigger fish, but one can be that much less of dilettante by digging deeper and mastering the why, not the what or the current fashion.
- inetsee 8y agoThe page containing the link to this pdf "https://www.agner.org/optimize/" https://www.agner.org/optimize/" has links to four other pdfs describing other topics on optimization.
- ignoramous 8y agoClickable and non 404: https://agner.org/optimize/ https://agner.org/optimize/
- inetsee 8y agoSorry, I had forgotten that HN doesn't like quotes around links.
- heyjudy 8y agoI still remember the olden days when XOR AX,AX was faster than MOV AX,0 and Abrash'es book was the magnum opus of the pre-P6 era. I guess I better throw most of those assumptions out for modern microarchitectures.
- caf 8y agoThe XOR is still idiomatic because it is smaller than the MOV, because the immediate zero has to be encoded as the same size as the destination register.
- kijiki 8y agoProbably not directly faster, but "xor %rax, %rax" is still smaller (and thus faster if you're icache constrained) than "mov $0x0, %rax"
- userbinator 8y agoIt is still faster because the register renamer handles it --- ditto for "sub reg, reg": https://randomascii.wordpress.com/2012/12/29/the-surprising-subtleties-of-zeroing-a-register/ https://randomascii.wordpress.com/2012/12/29/the-surprising-...
- jabl 8y ago"xor %eax, %eax" is even smaller (2 bytes vs. 3) and does the same thing since operations on the 32-bit subregisters are defined to zero the upper half [1]. This is what compilers tend to do when they want to zero a register. [1] This is not true for 8- or 16-bit subregisters, causing all kinds of fun issues (see "partial register stalls", also discussed in Agner Fog's materials).
- bogomipz 8y ago>"and Abrash'es book was the magnum opus of the pre-P6 era." What book is that?
- vnorilo 8y agoProbably Zen of Code Optimization. Good times.
- bogomipz 8y agoI've heard this individual's name come up quite a few times(it's very distinctive)in discussions about the compiler/optimization/cpu architecture space. Does anyone know if this individual still teaches at the Technical University of Denmark and if there might be any lectures of their's online? I've been watching Onur Mutlu's CMU lectures online and this material is a nice addition to computer architecture self-study.