Advertisement

Optimizing IFs

Started by February 18, 2000 10:03 AM
13 comments, last by Yanroy 24 years, 7 months ago
If the IF is really slowing you down (please tell me the profiler is telling you so), try to do the following:

Make it exremely predictable. (Assuming a PPro/II/III) if the CPU guesses correctly, the branch is a cycle. If it guesses incorrectly, it can cost up to 14. The PIII uses, I think, a hybrid predictor with a 2-bit predictor (4 states, strong taken, weak taken, weak not taken, strong not taken) which does really well on branches that are either always taken, or always not taken, and a multi-bit predictor that is used to predict certain _simple_ patterns.

If the branches still are too costly, look into using conditional moves. They have no branch penalty, and can be used for simple if() constructs. They''re on nearly all modern processors, like Alpha, and IA64. They''re even on the PPro and above, but given the extremely register starved nature of the x86 you may have trouble using them.
Well, you can maybe try using conditional operators in some parts.
Instead of
/* what you may be using to toggle between on and off */if(flag) flag=0;else flag=1;/* or may have it expanded slightly */if(flag==1) flag=0;else flag=1;/* you can try this instead - look up conditional operators in your helpfile */flag=flag?0:1;/* You can use them in things like, lets say this *//* Instead of this */passed=my_function(value);if(passed) sprintf(string,"my_function(%i) was successful\n",value);else sprintf(string,"my_function(%i) was unsuccessful\n",value);MessageBox(NULL,string,"Title",MB_OK);/* you can use */passed=my_function(value);sprintf(string,"my_function(%i) was %s\n",value,passed?"successful":"unsuccessful");MessageBox(NULL,string,"Title",MB_OK);/* or preferably */sprintf(string,"my_function(%i) was %s\n",value,my_function(value)?"successful":"unsuccessful");MessageBox(NULL,string,"Title",MB_OK); 
Advertisement
That goes for if you are using C or C++ though.
I honestly think your over-optimizing here. In fact, there are probably only a couple of functions in a game that are called often enough to warrent optimizing them to such an extreme degree (I''m thinking stuff like blitters). Low level optimizations are an OK thing, but if something is slow you should probably look to more high level optimizations first.

--TheGoop
I used to optimize expressions like if ( expr1 && expr2 && expr3 && ... && exprN ) using asm to use just one conditional jump. The main idea is to use setcc r8 for each exprN, sum the values of r8 and then check the sum against N.

Suppose you have the following code:

if ( ( a==b ) && ( c>d) && (e<f) )
{ something }

This can be optimized like this:

unsigned char ntrue;// ... something ...__asm{   mov  eax, a   cmp  eax, b   sete cl   mov  eax, c   cmp  eax, d   setg bl   add  cl, bl   mov  eax, e   cmp  eax, f   setl bl   add  cl, bl   mov  byte ptr [ntrue], cl}if ( ntrue == 3 ){ something } 


For 'or-ed' expressions you will just check if ntrue>0, and for mixed ones you will have to do some tweaking.

Edited by - Dummy on 2/21/00 5:01:33 AM

This topic is closed to new replies.

Advertisement