• Create Account

Calling all IT Pros from Canada and Australia.. we need your help! Support our site by taking a quick sponsored surveyand win a chance at a \$50 Amazon gift card. Click here to get started!

# Misterious (or not) slow performance

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

14 replies to this topic

### #1Juliano Schroeder  Members   -  Reputation: 121

Like
0Likes
Like

Posted 08 December 2011 - 06:05 AM

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.

### #2Álvaro  Crossbones+   -  Reputation: 16526

Like
0Likes
Like

Posted 08 December 2011 - 06:17 AM

Use a profiler to identify where your program is spending its time.

### #3way2lazy2care  Members   -  Reputation: 782

Like
1Likes
Like

Posted 08 December 2011 - 10:32 AM

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.

### #4Juliano Schroeder  Members   -  Reputation: 121

Like
0Likes
Like

Posted 08 December 2011 - 10:45 AM

@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.

### #5Tournicoti  Prime Members   -  Reputation: 699

Like
0Likes
Like

Posted 08 December 2011 - 10:55 AM

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 ?

### #6Juliano Schroeder  Members   -  Reputation: 121

Like
0Likes
Like

Posted 08 December 2011 - 11:03 AM

Hmm, I'm not sure. How can I enable/disable VSync?
http://www.creationguts.com - The Guts of Creation
drawing, programming and game design.

### #7Tournicoti  Prime Members   -  Reputation: 699

Like
0Likes
Like

Posted 08 December 2011 - 11:07 AM

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


### #8Juliano Schroeder  Members   -  Reputation: 121

Like
0Likes
Like

Posted 08 December 2011 - 11:30 AM

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.

### #9way2lazy2care  Members   -  Reputation: 782

Like
0Likes
Like

Posted 08 December 2011 - 11:51 AM

@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.

### #10Juliano Schroeder  Members   -  Reputation: 121

Like
0Likes
Like

Posted 08 December 2011 - 12:12 PM

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.

### #11way2lazy2care  Members   -  Reputation: 782

Like
0Likes
Like

Posted 08 December 2011 - 12:24 PM

Well, if I comment out nothing happens hehe, so the framerate will probably go up.

Unless the problem isn't in that function :-p

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.

Put it in your game loop. Your physics shouldn't depend on your graphics at all so keep them as separated as possible. That's more than likely what the problem is at the core.

### #12rip-off  Moderators   -  Reputation: 9888

Like
0Likes
Like

Posted 08 December 2011 - 12:31 PM

You can improve this naive collision loop by having the inner loop move from it1 + 1 to end, rather than comparing every single object against every single other object. To make this work you would need to notify both objects of a collision when it occurs in the inner loop.

You could also decide to test the world first and skip the test against other objects (assuming that world collision is the most frequent type of collision), depending on what "stop()" does.

### #13Juliano Schroeder  Members   -  Reputation: 121

Like
0Likes
Like

Posted 08 December 2011 - 12:42 PM

I'm using glut and i put everything on my drawFrame callback with glutDisplayFunc(). The other callback i can set is through glutIdleFunc() but I don't know if it would be consistent to put my physics in the Idle callback and the rendering in the drawing callback.

I think it could be said that my game loop for now is the drawFrame function. Don't know exactly how I can improve it.

Another note: the physicsystem doesn't depend on the graphics it is just called before the graphics are drawn.
http://www.creationguts.com - The Guts of Creation
drawing, programming and game design.

### #14Juliano Schroeder  Members   -  Reputation: 121

Like
0Likes
Like

Posted 08 December 2011 - 12:47 PM

You can improve this naive collision loop by having the inner loop move from it1 + 1 to end, rather than comparing every single object against every single other object. To make this work you would need to notify both objects of a collision when it occurs in the inner loop.

You could also decide to test the world first and skip the test against other objects (assuming that world collision is the most frequent type of collision), depending on what "stop()" does.

Good idea. I would need to put a collided attribute in the Box object to notify both of them. As for now the boxes only fall and collide to each other and to the bottom of the world. Stop() only sets the Box::direction attribute to 0.

The code that moves the box is actually like this ( I omitted direction to make it clearer):
 b1.setXY(b1.getX(), b1.getY() + b1.getDirection() * this->gravity); //gravity is 0.001f


Box::direction defaults to -1 and stop() sets it to 0.
http://www.creationguts.com - The Guts of Creation
drawing, programming and game design.

### #15Vortez  Crossbones+   -  Reputation: 2705

Like
0Likes
Like

Posted 08 December 2011 - 01:19 PM

For vsync in opengl, try this:

// OpenGL VSync Extension
typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int);

PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT;

void SetVSync(int i){
if(wglSwapIntervalEXT)
wglSwapIntervalEXT(i);
}

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS