Jaymin Kessler

@okonomiyonda

2011 April 1st

In this rant, I would like to address certain misconceptions regarding program performance on modern hardware.  Many programmers, not just amateur but also professional, do not properly understand the true responsibilities of the console game programmer.  This is mainly the fault of the so-called twitter gurus such as Mike “Acton like a damn fool” Acton, Tony “cow blood” Albrecht, and Steven “nonconversant” Tovey.  In this article, I would like to provide a counterbalance to their rhetoric, and explain why no programmer should ever be thinking about low level hardware details

Don Knuth, circa 1987

I want to begin with a quote from Donald Knuth, the father of theoretical computer science, that I believe we should all be familiar with.  Please open your book of Hoare to page 671, chapter 5, verse 11.  Was it not Donald Knuth, father of the C programming language, that said “optimization is evil, and therefore you shouldn’t do it”? Even more true today than it was back then.

Who are we to argue with Knuth, the man who discovered boolean logic?  Optimizer is one of those jobs on the way to extinction, like gas street lamp lighter, town crier, and Haskell programmer.  And when Donald Knuth, creator of the electrical force described in Ohm’s Law, tells you something is useless, you better believe it is!

Assembly, or as I like to call it, the dumbest most pointless language evar

“Peer review!”  – Christer Ericson

The radical optimizationist will tell you that a major tool for optimizing any piece of code is to rewrite it in assembly.  If anyone tells you that they got some speedup from rewriting code in assembly, they are telling you a story from 60 years ago, or they are genuinely stupid.  The very idea of believing that you can make something run faster by writing it in assembly is rooted in ignorance.  People who make such audacious statements probably aren’t aware that since the mid 1940’s, compilers have been outputting assembly from your C++ code.  Thats right.  Converting your C++ to assembly is exactly like replacing your integer divisions with shifts: the compiler is already doing it for you and it will result in nothing more than you wasting your precious time.

Also, in this day and age of multicore CPUs and giant PS3 clusters, you really don’t get much of a speedup from micro-optimizations anymore.  The real speedup comes from using parallel resources efficiently.  I would argue that assembly is a woefully inadequate language for an increasingly parallel world, and here is why.  In order to do any kind of parallel programming, you need library support.  This is a fact.  Not only does assembly not have any mutex and semaphore support in its standard library, but it also doesn’t even have any job manager API.  I’m sorry, but that right there kills any illusion of usefulness the language may have once had.

Furthermore, instruction scheduling is a hard problem.  In fact, finding an optimal schedule isn’t just hard, its NP Complete. If you have never heard that term before, NP Complete is mathematician shorthand for No Person but a Complete idiot would try to solve this.  Think about it.  Grab a pen and paper and start writing some code.  How long would it take you to write out a whole program? A minute? 5 minutes? If there is one thing computers are good at (aside from responding to commands like ZOOM IN and ENHANCE RESOLUTION) its trying lots of things really fast.  A compiler can loop through every program in existence until it finds one that matches your C++.  You can’t compete with that, so why not just let the compiler do its job?

So what about the Fox Mulders of the computer world, with their paranoid conspiracy theories about compilers being untrustable?  Maybe when they were young they had a fortran compiler they were close with inappropriately touch their “special” file, and they now are traumatized.  Continuing with the X-Files analogy I’d say that Acton, Albrecht, and Tovey are more like the Lone Gunmen, where Acton is the guy with the blonde hair and glasses that everyone liked, Tovey is the guy with the short hair and beard, and I can only assume Albrecht looks like that third guy because no one has ever seen a photo of him.

But my point is this.  Compilers are expert systems, and as such always do the right thing.  In fact, compilers are so good at what they do that the term “compiling” was named after them!!  But really, I wouldn’t expect you to believe any of this without proof.  Only the radical optimizationist forms half-assed opinions without first verifying them to be true.  Take for example the following code:

1
 
  
 
1
 
  2
 
  3
 
  4
 
  5
 
  6
 
  7
 
  8
 
  9
 
  10
 
  11
 
  12
 
  13
 
  14
 
  15
 
  
int RealWorldFuncExample(void)
 
   
 
  {
 
   
 
      return 5;
 
   
 
  }
 
   
 
  int main(void)
 
   
 
  {
 
   
 
      int complex_deep_nested_expression =
 
          RealWorldFuncExample();
 
  }
1
 
  
 

Lets take a look at what the compiler does with this by LOOKING AT THE ASSEMBLY, something a programmer should never ever have to do!

1
 
  
il r4, 5

Admittedly, I have no idea what that means, but its ONE SINGLE LINE OF CODE!  This sentiment that compilers can’t be trusted is obviously a carryover from the dark ages when compilers didn’t optimize things for you.  Provably the compiler always Does The Right Thing.  Actually, speaking of inlining, this brings up another good point I wanted to mention.  Did you ever notice how C# has no inline keyword? That is because the incredibly forward thinking engineers at Microsoft (a company headed straight to the top if there ever was one) realized that compilers are way better at deciding what should be inlined than a programmer.  Come on, look what happened in C! They let the “C-partiers” decide what to inline, and being of questionable intelligence, everyone ended up inlining everything.  Do you really want the power to decide what gets inlined in the hands of idiot programmers like yourself?  No, only Donald X. Knuth, shaolin grandmaster and Mortal Kombat thunder god, should have that power.

Move Forward, Not Back

As a society, we tend not to invent things that are worse than things we already have.  Think about it.  We invented artificial flavors because they are better than natural flavors.  If natural flavors were better, than we would never need to invent new chemicals.  Its the same thing with languages.  We invented C++ because it was superior to assembly.  If assembly was better, by definition C++ wouldn’t exist, and C++ most certainly exists.  We have all kinds of new algorithms and fast computers with lots of memory that make C++ practical now, and there really is no reason to go back to the dark days of register allocation (unless you mean allocating callbacks to register with your awesome new callback design pattern!)

Object Oriented Programming, or OOP, represents a new paradigm that revolutionized computer programming to the extreme.  Its main benefit was the ability to allow programmers to think about their program using analogies that made sense to humans, instead of thinking about boring hardware details which always just change all the time anyway.  The same strategy of forcing the people way of doing things on machines was deployed by computer vision researchers with phenomenal success.  It turns out that taking something non-human like a computer and trying to force it to see in the same way humans see was the best possible way for computers to make sense of the world around them.

Now some people will whine and moan about the performance effects of OOP, but I don’t see it that way at all.  When you change the way you write code for some specific piece of hardware, all you are really doing is rewarding the incompetence of hardware designers.  Do you really want some ivy league fat cat hardware designer in his cushy tokyo skyscraper corner office dictating to you what makes your code good or bad? Hells no, you don’t!  Its not our job to tailor our code to their hardware, but rather it is they who must tailor their hardware to our code!  We didn’t land on the PPU, the PPU landed on us!

Its time we as programmers stood up for the abstractions that set us free and make our code so wonderfully unreadable.  If we wanted to think about machine architecture, we would have become electrical engineers.  No, we must not let the IBM nanny state tell us what we should and shouldn’t do.  In the end, there must only be freeeeeeeedom!!1!

In Conclusion

If you should ever find yourself thinking you want to be a low level programmer, try this.  The next time your mom asks what it is you do for a living, try telling her “I’m just a low level programmer.” I’m willing to bet she responds with something like “Oh no, hunny, thats not true. I’m sure lots of people think your work is important.”  See, even your mom knows low level is a bad thing!

Finally, I wanted to provide an example of just the kind of idiotic trickery that no programmer should be engaging in.  The best example I could find was this pointless garbage