5 ms·
> "modern computers are very complex, don't even try to understand what's happening" One thing to keep in mind is that the CPU is no longer the CPU you think i
by jdcarter 9y ago
> "modern computers are very complex, don't even try to understand what's happening"
One thing to keep in mind is that the CPU is no longer the CPU you think it is. While the x86 instruction set used to directly control the processor, today it's just a compatibility shim. Under the covers, the CPU is converting your assembly into its own microcode and it's that microcode which is doing the real work. For example, look at some of the block diagrams in section 2 of this Intel manual:
https://software.intel.com/sites/default/files/managed/a4/60/253665-sdm-vol-1.pdf https://software.intel.com/sites/default/files/managed/a4/60...
Combine that with all kinds of other voodoo they've added--fancy caches, branch prediction, and so forth--and the "don't even try" maxim starts to make sense. I'd amend that to say "don't even try unless you're just curious."
Personally, I think assembly is a great learning tool, e.g. for understanding how pointers work, how the stack works vs. the heap, how function calls work, and so-forth. I was exposed to Motorola 68K assembly in college and it completely changed my world--lots of C++ things I considered voodoo suddenly made total sense. But I've never used assembly in production code and probably never will.
- dws 9y agoThe CPU is no longer the CPU that the CPU designers (often) think it is. A few years back someone who worked on CPUs at Intel related how his group pulling their hair out trying to characterize how a small section of code in a loop could have wildly different performance characteristics depending on the preceding instructions.
- mark-r 9y agoThe Motorola 68K was nearly ideal for assembly programming. You're lucky to have learned on it.
- jdcarter 9y agoOh very much so, 68K was great. Even better, at my first job we had a custom 68K-based embedded device and no source-level debugger, so you could only debug in assembly. That reinforced everything I had learned just a few years before. Our next device was MIPS-based, and MIPS was a great RISC system to learn on. I count myself very blessed.
- westmeal 9y agoFor someone attempting to learn 6502/10 assembly hows the C64 for this?
- mmphosis 9y agoAs someone who has used assembly in production code, I am much more than merely curious. I would like to assemble / generate microcode directly. I would like to know exactly what the CPUs are doing, and not rely on voodoo.
- mikebenfield 9y agoI have the same instinct, but I think in a few years we'd be in the same position, where what we write doesn't directly correspond to the architecture of the CPU. The CPU people are always going to work to make existing code faster, and since it's impossible for many generations of CPUs to "be just like the last generation, only faster", that's inevitably going to involve some kind of translation layer between your code and the CPU's "real architecture."
- vram22 9y agoWon't the translation layer reduce some of that extra speed? And if so, why is it done? so that people can keep programming to the same instruction set, even though the underlying (micro)code and hardware architecture has changed?
- mikebenfield 9y agoHere's my informal and possibly screwy understanding of why translating to microcode doesn't really slow things down: When you've got a bunch of tasks to do, breaking the task-execution process into a pipeline of steps may potentially increase the latency (how long does it take to do a single task), because, well, you've now got to go through several steps do do that task. But (assuming your pipeline is designed well), it will also increase the throughput (how many tasks can you do in a fixed amount of time). In software, it's likely that latency is not going to be a problem as long as you can get more throughput (you probably don't care if the time between when the program hits your opcode and the CPU actually executes your instruction is 1 nanosecond later than it conceivably could be as long as the number of instructions executed per millisecond is greater). In any case, yes, you need to expose the same machine code interface, not just so people can write new software using the same code, but so that old code continues to work. It would be a nightmare if every few years there were incompatible changes to the instruction set.
- CalChris 9y agoAnother thing to keep in mind is that the compiler is still pretty much the same compiler you think it is. This is the case because it is very difficult to codify all of the information in the Intel Optimization Manual [1]. It's a harder thing to use that information and then a harder thing still to codify, use and use correctly all that information for multiple targets and architectures. LLVM Tablegen is an approach for representation but it still requires the compiler writer to write everything down and then use it effectively and correctly. This is really hard and it doesn't get done. Instead someone ports a backend and then kinda sorta improves things until it seems better than it was. Intel has a fine compiler which goes further. It sure isn't open source and it costs a few bucks. They're also contributing LLVM now. The reason don't even try makes sense both for compiler writer and assembly writer is that this stuff is really hard. Also CPUs are damn fast and Intel (and ARM and ...) work really hard to solve problems dynamically (branch prediction, speculation, register renaming, caching, speculation, ...). In fact, you shouldn't even try this unless you know a lot. Agner Fog and Peter Cordes should be familiar names. But if you do know a lot, beating compilers is not difficult at all. Finding the right place to beat them? That's tough. [1] https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf https://www.intel.com/content/dam/www/public/us/en/documents...
- benchaney 9y agoEven though CPUs have got a lot more complicated, it is t that difficult to make intelligent decisions about optomizations at a high level of abstractions. There are situations where it makes sense to delve deeper as well. Not only because you are writing assembly, but also if you want to handhold the compiler. There are absolutely situations where it is not worthwhile to worry about optimizations. The problem is that the internet peanut gallery is rarely in a postition to give good advice about this.
- mrec 9y ago> I was exposed to Motorola 68K assembly in college and it completely changed my world--lots of C++ things I considered voodoo suddenly made total sense Heh. I had this the other way around - picked up 68k asm for fun long before C/C++, and couldn't understand why people had such difficulty with the concepts in those. I've never learned x86 - partly because I worry that I'd enjoy it too much and waste oodles of time "optimizing" things that don't need it. Probably useful to be able to at least read it, though.
- spc476 9y agoThe x86-64 bit isn't bad. You get 16 registers (half named, half numbered---historical baggage) and opcodes galore (more than even the VAX architecture). The x86-32 bit is a mixed bag (8 registers, the specialized opcodes may or may not be worth using depending upon which chip you use), but it certainly helps to know the history (the 8086 and 80286) to understand why it's the way it is. A few weeks ago I tried my hand at optimizing some code using the vector instructions. While I was able to beat clang quite easily using assembly, I just could not beat GCC. That was sobering. There's probably some 1000 page tome I have to read to understand where I messed up in optimizing.
- Coincoin 9y agox86 and 68K are night and day. x86 is no fun at all; there is way too much legacy stuff.
- deleted 9y ago[deleted]
- deleted 9y ago[deleted]
- harry8 9y ago"Don't even try to understand" _never_ makes sense. In this context it's the mantra of idiots who want to put dog-slow abstractions into C++ (among others). You have tried and you understand micro-ops exists, that branch prediction exists etc. This information is useful when optimising. If you never need to optimise C or C++ code why are you using these languages? Seriously? You've almost certainly got the wrong tool for the job. (Ok sometimes someone has made a legacy decision and you're stuck with it for bad reasons. Meh). If you don't try to understand it, you won't know things like "Never use a linked list if you care about performance at all." Even Bjarne has twigged to that one (at last!). C and C++ are languages you use when you need performance, understanding the CPU as best you are capable is crucial for performance. DO try. In fact it's insane not to work on your understanding. Don't even try to justify a statement of "don't even try to understand". It's wrong thinking from top to bottom. Here, as everywhere. No really.