Misterious (or not) slow performance

Started by
13 comments, last by Vortez 12 years, 4 months ago
Hello everyone,

I'm making a little piece of game to learn, so I'm kinda starting everything from scratch just to experience the difficulties. It is very simple by now, but I'm noticing a quick degrading in performance as soon as I start adding more elements to the system.

I have
  • a World object which defines world boundaries and a vector of box objects
  • a Box object that is the main element of the system
  • a PhysicSystem object that handles the boxes movement and collision
  • a Renderer class with static functions to draw the world and the boxes.

Here's the draw function:

void drawFrame() {

/* ... projection matrix settings .. */

physys.calcBoxPositions(); //calculates box movement and detect collision

Renderer::drawWorld(w); //draws the world boundaries
Renderer::drawWorldBoxes(&w); //draws each box
glutSwapBuffers();
}


The box movement is just a constant increment on the y axis. The collision detection each box to all the others and the world, if it detects a collision, it stops incrementing the box position.


void PhysicSystem::calcBoxPositions() {

std::vector<Box>::iterator it1;
std::vector<Box> &boxList = this->world.getBoxList();

for (it1 = boxList.begin(); it1 != boxList.end(); it1++) {
Box& b1 = *it1;

b1.setXY(b1.getX(), b1.getY() + this->gravity); //gravity is 0.001f

bool collided = false;
std::vector<Box>::iterator it2;

for (it2 = boxList.begin(); it2 != boxList.end(); it2++) {

Box& b2 = *it2;
if (&b1 != &b2) { // not the same box

collided = checkCollision(b1,b2);
if (collided) {
b1.stop();
collided = false;
}
}


if (b1.bottom() <= this->world.getY())
collided = true;

if (b1.top() >= this->world.getY() + this->world.getHeight())
collided = true;

if (collided) {
b1.stop();
collided = false;
}
}
}


I start the thing with 4 boxes and it runs smoothly. When I add like 5 more boxes the frame rate drops heavily. I know that the collision checking has square complexity, but I don't think that it alone is the problem with so few boxes.

Any council/help/suggestion/critic will be appreciated,
Thanks
http://www.creationguts.com - The Guts of Creation
drawing, programming and game design.
Advertisement
Use a profiler to identify where your program is spending its time.
Your blocks are nested wrong. You are checking against world collision N^2 times instead of N times. That's probably not it, but it's definitely a problem.


void PhysicSystem::calcBoxPositions()
{

std::vector<Box>::iterator it1;
std::vector<Box> &boxList = this->world.getBoxList();

for (it1 = boxList.begin(); it1 != boxList.end(); it1++)
{
Box& b1 = *it1;

b1.setXY(b1.getX(), b1.getY() + this->gravity); //gravity is 0.001f

bool collided = false;
std::vector<Box>::iterator it2;

for (it2 = boxList.begin(); it2 != boxList.end() && !collided; it2++) {

Box& b2 = *it2;
if (&b1 != &b2)
{ // not the same box
collided = checkCollision(b1,b2);
}
}


if (b1.bottom() <= this->world.getY())
{
collided = true;
}
else if (b1.top() >= this->world.getY() + this->world.getHeight())
{
collided = true;
}

if (collided)
{
b1.stop();
collided = false;
}
}
}


A couple things that I'd fix about your code that would involve more rewrites would be the following. Move your movement logic (b1.setXY(b1.getX(), b1.getY() + this->gravity); //gravity is 0.001f) to be completely separate from your collision logic. It will make it less confusing on the whole. Second, I would use Allman style indents (http://en.wikipedia.org/wiki/Indent_style). They are much easier to visually parse.
@alvaro: thanks, I'm gonna try some profiler in the future.

@way2lazy2care: yes, i realized they were nested wrong, I think it was when i copied the code to post, It didn't indent well and I removed some comments and code not related to the issue. Or maybe It was a mistake, need to check later.

I could put the internal for loop inside the checkCollision function and pass only one Box to it. Then the outer for loop move the Box and calls checkCollision(b1); and after calls a checkWorldCollision(b1);

Still, no idea why I'm having such a slow performance..
http://www.creationguts.com - The Guts of Creation
drawing, programming and game design.
Hello
How much do the performances fall ? I had a problem a bit like this, where performances drop to half suddenly when adding another entity, it came from the fact that I activated VSync. (wasn't able to have 60Hz frame rate, so it drops directly to 30 Hz due to vSync)
Do you enable VSync ?
Hmm, I'm not sure. How can I enable/disable VSync?
http://www.creationguts.com - The Guts of Creation
drawing, programming and game design.

Hmm, I'm not sure. How can I enable/disable VSync?


This is done when calling IDXGISwapChain::Present() (I talk about DX10 but there must be a similar way for other dx versions)

For example :


if (vSync)
g_pSwapChain->Present(1,0);// VSync
else
g_pSwapChain->Present(0,0); // presents the frame immediately
I'm actually using OpenGL, gonna check how it is done there. Thanks.
http://www.creationguts.com - The Guts of Creation
drawing, programming and game design.

@way2lazy2care: yes, i realized they were nested wrong, I think it was when i copied the code to post, It didn't indent well and I removed some comments and code not related to the issue. Or maybe It was a mistake, need to check later.


hum. Where do you call your calcBoxPositions? Maybe it's just getting called too frequently. If you comment out where you call it and the framerate jumps back up it would be kind of a way to isolate it to that function.

edit: If commenting out that line and turning off vertical sync both fix the issue independently (ie turning either one off but not both), then I'd suggest spinning your drawing code off away from your game logic so it can go run on it's own without having to wait for the physics stuff.

That said I don't feel like it's vsync, but that's more my gut than any reasonable explanation.
Well, if I comment out nothing happens hehe, so the framerate will probably go up. I call the function in my drawFrame function. It gets called every time a frame is drawn and I don't make any framerate control to set a specific FPS. It goes on its own accord.
http://www.creationguts.com - The Guts of Creation
drawing, programming and game design.

This topic is closed to new replies.

Advertisement