7 ms·
When I was still programming in C++ that tool was the method to discuss compiler internals and language semantics with colleagues. Just setup a minimal example
by choeger 4y ago
When I was still programming in C++ that tool was the method to discuss compiler internals and language semantics with colleagues. Just setup a minimal example and share it with your colleagues. Impressive and sad at the same time. Impressive for obvious reasons. Sad, because the language is so confabulated that there is no easy concise way to talk about its semantics.
- curiousgal 4y agoDo you all not need to understand assembly to advance the discussion?
- dtgriscom 4y ago... having trouble parsing this...
- School-Cotton 4y agoAssembly is not that hard to learn to read.
- einpoklum 4y agoNo, because: 1. You can figure out things about the assembly even without understanding assembly (e.g. lines of source translating into 0 lines of output vs many lines of output). 2. You have labels. 3. You can figure out some of the assembly on your own. Say: `mov %r1 %r2` - it probably moves what's in entity %r1 into a similar entity %r2, or vice-versa. etc. 4. You can see what the executable outputs 5. and most importantly: You can read compiler warnings and errors...
- whateveracct 4y agoYou can also RTFM and simply .. learn assembly.
- jfoutz 4y agoyes but there's real value in exploration. I haven't touched c or assembly for a long time. here's a cold read. push rbp this is going to take the contents of rbp and push it onto the top of the stack - this will probably also change the stack pointer mov rbp, rsp move goes left <-, like a = 5, not 5 = a. so, copy the updated stack pointer into rbp mov DWORD PTR [rbp-4], edi now, I'm not 100% sure, but I believe this guy puts edi just under the value we pushed to the top of the stack mov eax, DWORD PTR [rbp-4] Take that value, and put it into eax, I'm not 100% sure why it's not just mov eax edi. imul eax, eax integer multiply, this is the part that does the double. pop rbp restore rbp (which we messed with) ret and we're done. there are at least three holes in my understanding - but those three are not _that_ hard to track down. 1, does the stack pointer actually auto increment? (I think it does) 2, imul overflow and setting sign flags and such. - that shouldn't be hard to run down. 3, what is the c calling convention? it looks like the argument is top of stack, but also in edi - is that shuffling really needed? I think there's a bucket of implicit behavior there that's kinda scary. I would _hope_ unless linking to a library, whatever called this, just did the imul eax eax. My understanding may be deeply flawed, but explaining my assumptions and my understanding does two things. 1, it helps me learn. 2, it helps others re-evaluate their assumptions and possibly see from a different viewpoint. I'm not saying spam compiler lists. But a clear and well thought out question can certainly advance discussion. It forces people to formalize their assumptions.
- School-Cotton 4y agoThe default godbolt page runs the compiler with no flags, which means without any optimizations. This explains why the code unnecessarily shuffles stuff to the stack and back. Unoptimized clang/llvm output spills everything to the stack, and register allocation is an optimization. With -O3, the code is: imul edi, edi mov eax, edi ret Yep, the calling convention for x86-64 on Linux and macOS passes the first six integer arguments in rdi, rsi, rdx, rcx, r8, and r9, and then spills to stack.
- Sharlin 4y agoAnd Win64 in rcx, rdx, r8, and r9. Having originally learned the basics of assembly on the chronically register-deprived x86, it took me a while to get used to the fact that standard CCs now pass things in registers (and rsi and rdi in particular, retaining their ancient names while being completely general-purpose these days).
- throwawy6969 4y agoI think it has a few other languages supported now too. And/or there's equivalents for other languages. I think most of the confabulation of C++ is necessary to get the semantics needed for it to work right. Especially with all of the optimizations that compilers are expected to make. I found the reasoning behind switching from just rvalues/lvalues to the 5+ types they have now to be fascinating, for example.
- jeffbee 4y agoI also use it for this purpose, however I have come to hate the way other people use it for this. I have a colleague who has really no idea what he's talking about with respect to machine performance, and who did not have the requisite knowledge of how to peep at the assembly code of a given function with the standard tools like objdump, who now loves to send everyone godbolt links in slack, along with his suppositions about which function will be faster, based entirely on vibes (mostly, instruction count). This drives me up the wall. I wish there was some minimum height needed to ride godbolt.
- mwcampbell 4y agoIt's hard to measure performance in realistic situations; it's easy to measure code size. I recently found myself wasting time doing micro-optimizations, encouraged by the feedback loop of measuring and reducing code size (in my case, not with Compiler Explorer, but with "cargo bloat", since I was working on a Rust project.)
- sitkack 4y agoI know you know this but instructions are basically free in the face of memory access and random memory access is the worst. Linear scans over contiguous memory (per thread) generally optimizes performance. Instruction counts are only useful if everything is guaranteed to be in registers.
- slavik81 4y agoIt can be tough even without the impact of the memory hierarchy. I've seen code where adding an extra instruction to the calculation made it faster. The extra instruction implicitly eliminated denormals, thus resulting in faster execution with some workloads on systems where operations on denormal values were slower than operations on other values. It was a completely unnecessary instruction from a correctness perspective, because it had no effect on the answer. However, it was important for performance; removing the instruction made the calculation slower.
- nice_byte 4y agoI cannot imagine writing performance-critical software in _any_ language without a tool like this.
- pjmlp 4y agoMost compiled languages have offered switches to generate Assembly. Even on JVM and .NET there are ways to dump it, while on the various JVM implementations it requires a plugin if not using a debug build, on the .NET side, you can use show Assembly on Visual Studio, or make use of WinDBG with SOS plugin.