Rants on software, computing, and any other topic I feel like.

Tuesday, February 22, 2005

Optimization

I don't think that I would make a good game programmer.

A former coworker's life dream was to become a game programmer. Well it came true and I found myself wondering why someone actually hired him. Look, I've seen his code and have to work with it every day. Or more accurately, I play chicken with his code every day. I poke at it in some soft spot hoping that it will give way, only to find myself being thrown off in some other unforeseen direction. His code can't be modified without breaking at least 2 other things. It's like wack-a-mole. You pound down one of the little buggers only to have two more pop up.

So I assume that they took a look at his code at some point during the interview process. They must have seen the consistent use of sweet optimizations, like bit-shifting instead of dividing, reuse of variables because they cost so much you don't want to waste them, and using C arrays instead of std::vector because, well, C arrays just gotta be faster, because they're C. Being game programmers themselves, they probably saw the incredible value of all this. They also saw that he refused to cave into the C++ madness and still coded in C, using a C++ compiler. Because, it's just faster you know. All those objects are just too useful to be efficient.

In game programming, it is apparently a good idea to make calls to your database in an inner loop. My coworker did this all the time so it must be a good idea. I think I’m just uninformed, because last time I checked, database calls are pretty slow. I guess if you wrap them in a function that doesn’t *look* like a database call, then it’s okay. Or maybe simply putting them in an inner loop magically makes them faster. I wish I knew more about game programming. Maybe I can buy a "Game Programming for Morons" book at the mall and start working on becoming the next John Carmack.

Okay, so seriously, this coworker of mine actually got in an argument with me over the value of using bit shifting over a simple divide for integer division. Yes, I know everyone is taught that bit-shifting is really fast, but while I understand that no official announcement was made, compilers are now pretty good. They’ll recognize your divide by a power-of-two and convert it to a shift while you retain the readability of a divide. They’ll even make sure that it works for signed and unsigned numbers correctly. I even proved this to my coworker by showing him that the disassembly from even the MSVC++ non-optimizing compiler optimized this correctly. His response was something along the lines of, "oh, well, right, yea, but, well, what about pipelining?" Huh? Pulling out the technology of the week doesn't help you win the argument. I wish I mean enough to explain to him how stupid he sounds.

This is of course the same guy who doesn’t see a problem with casting to integer what should be simply left as floating point, because you know, integers are faster. We’ll just ignore the fact that casting from floating point to integer and back takes *forever*. And in the same code as he does his cast to integer, shift to divide (because it’s faster), and cast back to floating point, he makes one of the biggest game programmer gaffes, he writes:

pow(x, 2.0);

I mean, come on! This is why this blog is called Mad Software. This stuff just makes me want to scream. This isn’t just a game programmer thing, this is something that no one does. They just don’t. It’s far faster and just as readable to write:

x*x;

Now, this whole rant brings us to one of the first lessons of optimizing your code. Don’t optimize prematurely. All the above nasty is a perfect example of this: lots of optimizations at code level, without ever thinking of the global optimization problem.

You probably didn’t believe me when I said this guy was putting database calls into tight inner loops. Well, you’d be wrong. It was cleverly hidden in a conversion function, but it was a database call all the same. He never bothered to optimize it, or even did he recognize the fact that it was slowing the whole program down. That’s because he never did what a good programmer should do, profile his code. That is to find out what parts of the code actually are taking all the time. Guess what, it probably isn’t that really slow divide by two. It’s the database call hidden by a few layers of indirection that you’ll never see because you didn’t write the database code and didn’t realize that the guy that did is an idiot.

I assume that my coworker’s new employers saw these kind of things in his code because game programmers are the cream of the crop and don’t miss anything.

I just wouldn’t make a good game programmer, my code doesn’t suck enough.
Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?