Archived

This topic is now archived and is closed to further replies.

SikCiv

How do I optimize a frame loop?

Recommended Posts

My game has loads of Structs, and for each struct I have allocated many copies of the struct. For example I have a character struct which has about 50 vars... struct CHARACTER { bool bActive; POINT ptPos; RECT rcDest; bla blabla; bla etc; }; Then I assign about 100 instances of the same struct ... CHARACTER Character[100]; Each Character instance is "worked on" at every frame to calculate its new position and velocities etc.. therefore I loop through all the character instances about 5 times each. When I program, I make sure my functions work, so I dont do any optimizations until it works to my satisfaction. My problem is when I have over 50-70 characters (depends on the PC) the game loses frames BIG TIME. Obviously I have to optimize my code... But how? Question: Many of my functions use alot of temporary variables to do calculations. Is this good? For example:
UpdateVel(WORD n)
{

float newXVel;
WORD  ...
long  ...

// Here im using lotza temporary vars, 
// minimizing struct vars.

newXVel = Character[n].XVel + 10.0f * Delta;
Character[n].XVel = newXVel;
Character[n].XPos += newXVel;


}

 
Would it be better to do it this way...

UpdateVel(WORD n)
{

// Here im using no temporary vars, but im 
// using more struct vars.
Character[n].XVel = Character[n].XVel + 10.0f * Delta;
Character[n].XPos += Character[n].XVel;

}

 
What else can I do to optimize my loop even further?

Share this post


Link to post
Share on other sites
I really don''t know what kind of game you''re making, but if you can only see some of these characters at a time, you might be able to optimize it by just not processing the non-visible characters. Also, I would process everything at once for each character as follows:

UpdateChars()
{
for(int count = 0; count < 100; count++)
{
character[count].var1 = whatever + equation * you - need;
character[count].var2 = some / other + equation;
... and on and on ...
}
}

Also, I would use pointer notation instead of array notation for accessing the characters:

for(character* pChar = character; pChar < TopOfArray; pChar++)
{
pChar->var1 = YourEquationHere;
... and on and on ...
}

Share this post


Link to post
Share on other sites
I can''t say specifically what to do, but I can tell you how to find the problem. Measure how long differant tasks take. Start at the highest level and measure how long all the functions called from there takes. The timeframe is very small and you are unlikely to be able to measure one iteration accurately so you have to put a few loops in. You may well have to make a few other modifications since things change over time. As an example you may have to reset variables that got updated. You can measure how long that processing takes seperately and subtract it from the total. Once you find where the time is going from that level then move down to the examine that section in more detail. Once you are at a detailed enough level you can comment out sections of code. You then have to subtract how long it took without the code from the previous measurement to determine how long the commented out section took.

Share this post


Link to post
Share on other sites
try to do it in less passes, you said "about 5 times each". even if you can only get it down to 3, that''s a big savings. or maybe the bottleneck is actually in the drawing code of the objects.



crazy166
some people think i'm crazy, some people know i am

Share this post


Link to post
Share on other sites
I dont know much about this situation but one of the responses brought about a question in my head. Someone said that you don''t process the people that are off screen right? If someone moves though and they aren''t on screen, than how will you ever know if they move to on screen? Are you saying that you move everyone, but you just change certain attributes about people, like stuff thats gotta do with their visibility (animation frame, stuff like that) if they are on screen?

Maybe this will help in optimizing a little once this is settled, we can get a basic set of things that you need to change for people and a certain set of things that you should only change if they are on screen

Share this post


Link to post
Share on other sites
Well, the idea of not processing something unless its visible wouldn''t work for a RTS game, which is I think what you''re doing. But anyway, what do you mean by "working on each instance 5 times"? Is that 5 times a frame? Or 5 times a second (which would only give you 5 frames a second)? If you''re doing it 5 times per frame then I think that''s one of your problems. A character''s AI state should only be worked on once per iteration of your game loop, not 5 times. I think this is the obvious problem that you''re having, unless I misunderstood your post and your not working on each character''s AI state 5 times a frame...

------------
- outRider -

Share this post


Link to post
Share on other sites
Thanks for the input, my game is a 2D platformer but it works like an RTS game, that is, all the sprites have to be updated all the time for a good reason. I actually found out why the game slows down, its because I was testing my game with hundreds of sprites on the screen at one time, and since half of them were mirrored, it slowed down the framerate. For some reason the GeForce 256 card doesnt support mirror blitting in hardware, so DX does it in software which if slooowww );. Although I am using very old drivers, ill try updating the drivers and see if that fixes my problem.

As with my other question, which is the best way...

    

UpdateVel(WORD n)
{
float newXVel;
WORD ...
long ...
// Here im using lotza temporary vars,
// minimizing struct vars.


newXVel = Character[n].XVel + 10.0f * Delta;
Character[n].XVel = newXVel;Character[n].XPos += newXVel;}
}

[/source]

Would it be better to do it this way...

[source]

UpdateVel(WORD n)
{
// Here im using no temporary vars, but im
// using more struct vars.


Character[n].XVel = Character[n].XVel + 10.0f * Delta;
Character[n].XPos += Character[n].XVel;
}




Share this post


Link to post
Share on other sites