Skip to main content
GameDev.net gamedev.net
🔒 Locked

Can I make any quick game optimizations? (SDL/C++)

Started by awertz Apr 13, 2007 at 8:48 PM 16 replies 3.7k views
Original Post
awertz
awertz
My situation is I created a game for my intro to comp. engineering class which is due monday. The game is complete but it's having lag issues at higher resolutions. While I could just run it at lower resolutions, I know my laptop can support much better framerates than what I'm getting, so I'm going to try to describe what I am doing in my game and perhaps someone can give me hints on optimizing parts? First off, I'm using SDL (not with OpenGL) with the standard SDL input method (while (SDL_PollEvent...) which I heard wasn't spectacular as far as getting your CPU's worth. I'm not sure if this is something I can optimize (or if it would make a noticable difference if I did). Second, the game idea is simple: it's basically the multiplayer part of bomberman but with a few differences. You have the tiled map and then objects which are drawn on top of that (not just tiles that are blocking / non-blocking). The tile map is just a 2D array that was drawing all the tiles every frame. I tried to optimize this by adding a "dirty" property and every time an object is updated it calls any overlapping tiles dirty and they will be blitted. However, most of the screen is covered with objects, so I suppose this can be further optimized by focusing only on objects moving or animating. Objects are just stored in a list sorted by draw priority then Y value. Every frame they're all updated then drawn. I suppose an optimization I can make is to only redraw objects that were dirtied by a moving or animating object, and thus those non-moving objects wont dirty tiles like they do now. Besides those few things, I'm not sure how I can optimize my routines or whether the time spent implementing that stuff will make a noticable difference. I know you don't have my code, but perhaps some of you from experience know potential bottlenecks and errors beginners make? If you want code samples and what-not, let me know. Any help is greatly appreciated! Edit: Additionally, nothing is being specified as hardware surfaces. Not sure if that helps. But here's a sample map so you know what I mean: http://img178.imageshack.us/img178/1127/samplemapzz1.jpg
Aressera
Aressera
it would be multitudes faster if you were to port the drawing to OpenGL, I don't really know what else you could do at your current state.
awertz
awertz
People got by with tiled games before this with no hangups. On my computer (Athlon X2 - 2GB ram - 7600GT) I should not be seeing any lag for a simple tiled map and a few objects. I'm definitely doing something wrong.
nagromo
nagromo
I'm not sure if modern cards support 2d hardware acceleration. If they do, making everything use hardware surfaces could provide a speed boost, but vendors might have dropped 2d hardware acceleration entirely.

Either way, 2d is a lot slower than 3d; as was said, porting to OpenGL would be the biggest boost, but it's a lot of work.
zedz
zedz
SDL_PollEvent wont be the problem
ive never used sdl graphics (only with ogl)
perhaps its something to do with the transparency of the shadows.
to test turn off all transparency somehow (dont know how to do it in sdl)

-i believe a new version of 2d sdl graphics will use opengl under the hood, thus u will get hardware acclerated blending/rotation etc
Byron
Byron
You really need to identify if it really is the rendering that is causing you issues. I am not familiar with SDL but with something like DX you can minimise the viewport to as small as possible to that your application is still rendering but the fillrate is reduced and then what you are timing is the CPU side.

There are a few easy optimisations that can be done to pretty much any game:

First, if you are using classes for everything you can make your code more cache friendly by grouping the most used member variables towards the beginning of the class. For example, if for some reason each tile in your game was represented by a class try to keep the class size as small as possible and group the most used variables towards the 'front' of the class. The idea is that if you have to iterate through all of the tiles then by just accessing one tile instance chances are you have also pulled other tiles into the cache so the CPU doesn't have to do a main memory access - this kind of thing is important for particles.

While we are on the subject of the cache - linked lists. While they are great they also destroy locality of reference because chances are if a linked list is built dynamically then iterating through a linked list destroys cache lines each time you access each element. One way around this (but not perfect) is to only allocated new elements from a pooled resource of elements that were allocated en-masse so are more likely to be close to each other in memory.

Beware of temporaries and constructors. Get to know when your compiler will produce temporaries - especially if those temporaries are class instances because each class instance causes the constructor to be called and destructor when the class goes out of scope.

There are lots of other easy optimisations but you probably don't have time to implement them all.
ByronBoxes
onthetweek
onthetweek
Are you sorting all the objects every frame before drawing them?
It'll make quite a difference what sort your using.

Likely, you only need to do a sort when an object moves. In which case, you'd just do a single remove and insert for the moved object.

That's the only non-rendering thing I can think of.
rip-off
rip-off
Read. Particularly the one about hardware surfaces. See if anything there that might help you.

If you are using alpha blending, force all your surfaces to be software surfaces. Using hardware surfaces can result in slowdowns in a suprising number of situations, so watch out.

Have you profiled your code to see where most of the time is spent?
Barius
Barius
If you aren't already using it, use SDL_DisplayFormat for converting your sprites/tiles after loading them.
Julian90
Julian90
I suggest you download AMD CodeAnalyst* and profile your application which will tell you exactly what amount of the time is spent running each line of code in you program. More likely then not there will be 20-30 lines of code which are taking up the majority of the time and you can focus on just optimizing those lines.

* It works fine on non-AMD hardware
Ravuya
Ravuya
One of the big things I've found improve SDL performance is to specify SDL_ANYFORMAT as one of the flags when creating the initial SDL video mode.
MindFlayer
MindFlayer
I used glSDL in a previous video engine of mine and it really helped with my frame-rates (went from around 50 to way over 300). Basically, the library wraps most of the SDL rendering functions into OpenGL ones so you don't have to modify any of your earlier code.

Unfortunately, the library is no longer actively developed but I guess you should still try it out. here's a linky.
awertz
awertz
Thanks! Your responses were very helpful.

As for the profiler, I've been having problems getting it working on this specific project, but I have no clue why. It crashes many times and others it just (for some reason) doesn't load the symbols or source so I have no clue what's taking up the processing time.

As for the linked list remark, I do use a linked list for all objects, but it's not a real big list. However it is doing a merge sort every frame, which I realize is a horrible idea. (Although the merge sort doesn't seem to make a difference...).

I'm pretty sure the problem lies in the blitting. If I turn off the tile drawing all together it runs a lot quicker. However, my program still maxes out the CPU usage, and I have no idea why.

This summer I am going to take some time to learn 3D development. It seems like that's really the best route.

Edit:

If you'd like to see / critique the project (I'd be very happy if you did!) check this forum post:
http://www.gamedev.net/community/forums/topic.asp?topic_id=443959

[Edited by - awertz on April 16, 2007 10:28:11 AM]
Byron
Byron
Quote:
Original post by awertz
Thanks! Your responses were very helpful.

As for the profiler, I've been having problems getting it working on this specific project, but I have no clue why. It crashes many times and others it just (for some reason) doesn't load the symbols or source so I have no clue what's taking up the processing time.


You can go down the route of building a hierachical profiler into your code - one of the Game Programming Gems books had one in (sorry, can't remember which).

Quote:

As for the linked list remark, I do use a linked list for all objects, but it's not a real big list. However it is doing a merge sort every frame, which I realize is a horrible idea. (Although the merge sort doesn't seem to make a difference...).


Try the suggestion of pooling memory from a contiguous block for the linked list elements to help the cache.
ByronBoxes
Rattrap
Rattrap
Quote:

I'm pretty sure the problem lies in the blitting. If I turn off the tile drawing all together it runs a lot quicker. However, my program still maxes out the CPU usage, and I have no idea why.


Are you doing any kind of Sleep call in between drawing frames, or are you running it as fast as possible?
"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]
zedz
zedz
stick a SDLWait(5); call once a frame
it might be SDLDelay(5); check the syntax
blackcloak
blackcloak
I have been using sdl in my graphic engine and the biggest things that seem to slow down biting are:

surfaces with alpha channels epically if the alpha channel is not opaque or total transparent. This is very true with large surfaces or surface that have been antialiase

biting surface that are not the same bit depth as the screen surface

if you are doing any rotation or scaling with something like sdl_gfx this can also impact performance.


and one last this I agree with zedz you have to put a delay in your render loop or sdl and your code will eat up as may cpu cycles as the can


I hope this helps
Black CloakEpee Engine.
Kylotan
Kylotan
And there's nothing wrong with eating up as many cycles as it can, so don't put a Sleep() or SDL_Delay() in there unless you deliberately want it to run slower.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.