There is a very nice article about writing fast math library on gamasutra. It shows for example that using operator overloading generates slower code than when using functions. A lot of people believe that compiler will generate better code than a programmer can. They just happily write code and don’t check that their compiler generates.
Let’s test how good is VC++ against simple algebra and OOP crap :). I decided to be not too harsh, so I omitted here topics like SIMD, FPU or aliasing. I have chosen VC++ 2008, because it’s the most popular compiler in gamedev industry (and I think it will maintain it’s position until the VC++2010 SP1 release 🙂 ).
Default release build settings – /O2 etc. + very simple test cases, just int main(), scanf and printf.
// x/x = 1 int y = x / x; 00401018 mov ecx,dword ptr [esp+8] 0040101C mov eax,ecx 0040101E cdq 0040101F idiv eax,ecx
mov and idiv? FAIL.
// 0/x = 0 int y = 0 / x; 00401018 xor eax,eax 0040101A cdq 0040101B idiv eax,dword ptr [esp+8]
Another idiv, but at least compiler uses xor instead of loading 0 from memory.
// z = x * x // w = z * z // y = w * w int y = x * x * x * x * x * x * x * x; 00401018 mov eax,dword ptr [esp+8] 0040101C mov ecx,eax 0040101E imul ecx,eax 00401021 imul ecx,eax 00401024 imul ecx,eax 00401027 imul ecx,eax 0040102A imul ecx,eax 0040102D imul ecx,eax 00401030 imul ecx,eax
It was also too difficult for the compiler.
Ok, so maybe let’s try some OO code?
class Object0 { public: void virtual Print() { printf( "a" ); } }; int main() { Object0 *obj = new Object0; obj->Print(); return 0; } 0040101E mov dword ptr [eax],offset Object0::`vftable' (402104h) 00401024 mov edx,dword ptr [eax] 00401026 mov ecx,eax 00401028 mov eax,dword ptr [edx] 0040102A call eax
vftable? Another failure. Generated code can be fixed by writing obj->Object1::Print(); or removing virtual keyword.
Remember to hit alt+8 next time to open the disasm window :).