How Video Cards Work
x.org
x.org
http://en.wikipedia.org/wiki/Single-letter_second-level_doma...
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_TRIANGLES);
glVertex3f (-1.0, -1.0, 0.0);
glVertex3f (1.0, -1.0, 0.0);
glVertex3f (0.0, 1.0, 0.0);
glEnd();
Has been able to draw a red triangle for almost 20 years, on nearly every GPU released from a few dozen vendors. It transparently gets faster without you having to do much.As a result of everyone having to writing code like the above, as opposed to assembly code specific to each GPU, the GPU vendors have been able to change their architecture tremendously over the years to adapt to changing process technology tradeoffs and add new features.
They've been able to do this in part because 3D graphics is a well-enough-defined domain and can be reasonably API-ified, but I could easily see things having gone a different way; people would be arguing about whether the ARM of GPUs would conquer the x86 of GPUs, given the massive install base of the incumbent. Instead, to some extent, anyone who can write an OpenGL compiler can play.
The abstractions we have now are more complex than ever, but they are still, for the most part, in the problem domain -- it is possible to do weird things to your code for performance tuning, but it's just not possible to go as far with it as you can for a machine whose behavior is specified and guaranteed at a very low level.
It can be argued that all a CPU does is crunch numbers, but if you spend much time with a limited processor, you quickly realize a good CPU (or in my case MCU) needs to be very versatile and flexible.
Even CPUs' architectural transparency has its limits. You could squeeze a few percent out of your parallel code if you knew exactly how writes and reads were ordered on a particular system. As a rule, however, whoever made your CPU will not tell you; there's the 'trade secrets' thing, sure, but more importantly, telling you would impede their ability to do things a slightly different but better way next time, because your code would rely on the old behavior in ways that cannot yet be automatically detected or fixed. Instead, they specify a memory consistency model[1][2][3], an interface you can code to once and rely on for future generations.
[1] http://en.wikipedia.org/wiki/Consistency_model [2] http://en.wikipedia.org/wiki/Memory_ordering [3] http://en.wikipedia.org/wiki/Weak_consistency