Archive for February, 2006

The Compiler Knows What It’s Doing

Monday, February 20th, 2006

Numerous tests on AMX Mod/X have revealed that format() related routines are the biggest slowdown for normal operations. Format() works by copying a cell * to char *, parsing the char *, formatting the char * with blocks of cell * into a temporary buffer, then copying everything back into a cell *.

So, what did I try to do? Naturally, rewrite the thing in assembly. It took two days to get the exact same code in pure x86. The result? It was upwards of entire seconds slower.

This is a classic case of “the compiler knows what it’s doing“. In this case, the compiler was MSVC with full optimizations. Totally perplexed, I went and viewed the MSVC assembly for the format() function. Not only had it readily obeyed the “register” keyword hints, but it had crafted a function best optimized for x86 branch prediction and register usage. Even when I crafted my own assembly using the same tricks, I could not beat the speed of the compiler.

The second lesson learned from this is you can’t always optimize by going to assembly. Sure, it can help in some areas (upcoming article on JIT optimizations I’ve done), but most of the time you need to take a step back and look at your code.

In this case, the correct solution was not to spend two days writing a character parser in assembly (if you thought it was ugly in C…), but to write new templatized printf() functions to eliminate the buffer copies (i.e., a printf that can accept any type as a buffer).

Trust the compiler. Usually.