==============================================================================
C-Scene Issue #05
Optimization Techniques - Part I
Platform: Non-specific
Steve Mertz
==============================================================================
This is my first article on the subject of optimizations. I plan to write
several others as I come across new and nifty ideas on how to make your
programs run faster.
This article is for the novice to intermediate programmer (most expert
programmers should know this stuff.) Most programmers wish that their programs
could run just a little bit faster (if not a lot faster.) Well within this
and following articles I will give some simple hints for speeding up your
programs.
This article will be dealing with two things: 1) Loops and 2) tables.
Loops!
One of the bottle necks of speed for most programs will be loops. Repeating
a simple or complex item over and over. There are a couple of ways of helping
this out. The first being loop unrolling and the second loop flipping.
Loop Unrolling
This is simply shortening the number of times you make a loop cycle. You do
this by doubling or tripling the code inside the loop.
Simple loop without unrolling.
for (i = 24; i < 100; i++)
moveShip(x, i);
Same loop with unrolling.
y = 24;
for (i = 24; i < 100; i+=2)
{
moveShip(x, y++);
moveShip(x, y++);
}
The second method is faster because it's checking whether or not we are done
only every second time, rather than every time. This speeds things up because
of the lack of over head of the testing.
Loop Flipping
Loop flipping is where you take your loop and build it upside down. This one
is a little more technical why it works. When you are doing your for() loop
there are two operations happening. One is a conditional jump and the second
is an instruction jump. These can be costly if you have a lot of loop iterations
to go through. Here is an example of how to fix this.
Simple loop unrolled and no flipping.
y = 24;
for (i = 24; i < 100; i+=2)
{
moveShip(x, y++);
moveShip(x, y++);
}
Same unrolled loop with flipping.
i = 24;
y = 24;
do
{
moveShip(x, y++);
moveShip(x, y++);
i += 2;
} while ( i <= 100)
Again we used loop unrolling to help speed things up. Then by flipping the
loops upside down (doing the condition at the bottom) we lose 1 conditional
jump and 76 instruction jumps (one jump for each iteration.) So this speeds
things up quite a bit. And it's simple to do.
Tables
The next thing to think about is for those of you wanting to get into 3D
engines or other heavy mathematical type programs where you deal with a lot
of numbers that need to be calculated over and over is to use a table.
Instead of using sine or cosine to figure out angles every time you need one
you plunk them all into a table and use that. This does use up some memory
but most computers these days have more than enough to spare for these
tables.
Here is a simple example.
int i = 1;
do
{
printf("%i ", i * 5);
i++;
} while ( i < 20);
This simply prints all numbers divisible by 5. With that multiplication
it slows things down. So to speed things up we would do.
int i = 1;
int countFive[] = {
5, 10, 15, 20, 25 ,30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100
}
do
{
printf("%i ", countFive[i++]);
printf("%i ", countFive[i++]);
} while (i < 20);
Now that is a bit faster because we got rid of the complicated multiplication
which would slow things down. but because we just use an array we use the
index and look it up. And presto, we have the number.
You can also use this method for sines and cosines. But instead of typing in
all the tables, you could calculate all the values at start up. This will
make smaller code, and also speed things up after it's ready to go.
Stay tuned for more optimization tricks!
This page is Copyright © 1998 By
C Scene. All Rights Reserved