3 ms·
The x86 instruction set (and other instruction sets), abstract away much the underlying hardware architecture. The "flat memory" abstraction originates from and
by winter_blue 10y ago
The x86 instruction set (and other instruction sets), abstract away much the underlying hardware architecture. The "flat memory" abstraction originates from and is presented by most CPU instruction sets -- C just tries to be as close to a "generic" assembly language as possible.
I wonder when we'll get an instruction set that gives us fine-grained control over the different levels of caching, or even the ability to create FGPA-esque microcode functions, etc. Compiler writers could have the time of their lives with such an ISA.
- noelwelsh 10y agoI think with today's CPUs a generic assembly language would at least make a distinction between registers and memory locations. Programming with a conceptually infinite number of registers would be fairly simple and should make reasoning about memory locality easier. Current x86 CPUs have 192 registers internally, so you'd almost never go outside the register file unintentionally. I'm not very experienced with GPU programming, but my understanding is that the programmer has more control over memory locality there. Another point to remember is that CPUs have coevolved with programming languages. I think if languages tried to expose more detail in their machine model, ISAs might evolve to match this. Finally, hardware designers mostly aren't programming language people, and programming language people generally haven't been interested in languages in the same space as C (though that is changing.)
- telotortium 10y agoCPUs had registers back when C was invented too :) The reason C doesn't expose registers is because the flat memory model is more universal and more uniform between CPUs than the registers, which often have a lot of special-case behavior, especially on non-RISC CPUs: https://vanemden.wordpress.com/2016/03/15/why-does-c-not-have-an-exponentiation-operator-2/ https://vanemden.wordpress.com/2016/03/15/why-does-c-not-hav.... Besides, C has a "register" keyword, although it's probably ignored by almost all compilers today in favor of their own optimizations, which are usually better (and if they're not, you're usually gonna go to assembly for maximum performance anyway).
- nickpsecurity 10y agoThe reason C didn't expose registers is because it was specifically made to run on a PDP-7 and PDP-11. That's the sole reason for many of its internal decisions. Doing things differently than a PDP-7 or PDP-11 would've hurt performance. So, they kept it consistent whenever performance or complexity was critical. Decisions like that and x86 is why stack operations are still dangerous despite B5000 (1961) having protected stack and MULTICS (UNIX/C predecessor) having reverse stack immune to overflow. C kept the shitty PDP stack instead of MULTICS for performance. Reverse stack on x86 still has performance hit due to that decision. It's why Itanium did shadow stack in hardware. Not clever design or forward thinking. Just making it work on a PDP with long-term problems following.
- GFK_of_xmaspast 10y ago> The reason C didn't expose registers Uh ... http://ee.hawaii.edu/~tep/EE160/Book/chap14/subsection2.1.1.2.html http://ee.hawaii.edu/~tep/EE160/Book/chap14/subsection2.1.1....
- nickpsecurity 10y agoYeah, I've used the keyword myself but it was discouraged. Instead, we were taught to work with the local variables, stack, frame, heap, etc. It's technically in there at some point as a compiler hint but the internal structure reflects the PDP's. So, I partly take the comment back in that it was there but not standard practice.
- noelwelsh 10y agoI've done a bit of reading and I believe the blog post you linked is incorrect. For example, it claims that an innovation of C was to have assignment as a generalised move operation, rather than load and store operations (and introducing registers). One of the secrets behind C’s success is that just about any machine architecture has byte-addressable random-access memory. Moreover, pick just about any pair of machine architectures, and they differ in their register structures. By excluding registers from its computational model, C has hit the sweet spot in being close to the machine, yet not too close. So there is no place for LOAD and STORE in C’s computational model, while the assignment operator is an operation on random-access memory in the presence of an unspecified complement of registers. However Wikipedia claims this was an innovation of the PDP-11 ISA: https://en.wikipedia.org/wiki/PDP-11#Instruction_set_orthogonality https://en.wikipedia.org/wiki/PDP-11#Instruction_set_orthogo... Similarly, you can find many C features, like ++ and +=, mirror PDP-11 instructions (see https://en.wikipedia.org/wiki/PDP-11_architecture https://en.wikipedia.org/wiki/PDP-11_architecture, double-operand instructions for instance) Finally the PDP-11 had 8 general purpose registers, with two taken for program counter and stack. It seems that main memory loads cost about an extra cycle. So register allocation was not a pressing issue. There aren't enough registers to make sophisticated register allocation worthwhile, and you don't pay a high penalty on a register spill. This is in contrast to all modern machines (e.g. current Intel chips have 192 registers internally and a cache miss can cost a hundred cycles [http://stackoverflow.com/questions/4087280/approximate-cost-to-access-various-caches-and-main-memory] http://stackoverflow.com/questions/4087280/approximate-cost-...) I'm coming to the same conclusion as nickpsecurity: C was designed specifically to run on the PDP-11, taking advantage of its instruction set, and we're still paying the price of those decisions. It's interesting to imaging what a better low-level for, e.g, the Parallela Epiphany-V currently on the front page would look like. https://www.parallella.org/wp-content/uploads/2016/10/e5_1024core_soc.pdf https://www.parallella.org/wp-content/uploads/2016/10/e5_102... Highlights: - 64MB(!!!) of on-chip SRAM - 1024 processors - 64 registers