View Full Version : problem profiling a game with sdl
gringo
11-23-2005, 03:42 PM
Hi, I'm writing a small game in SDL. Unfortunately, my game seems to need at least a 2.0+ computer to run .. After profiling a little with vtune (because it is very simple, it must some problem somewhere)
I discovered that SDL.DLL takes like more than 80%, and inside SDL.DLL there is a function called 'SDL_FreeRW' that takes 99% of the time . I couldn't find out who calls it and why, but I want to get rid of it but I have no clue what to change or where. I have all my my SDL_Surfaces abstracted in a class called 'CBlitbuf' . I set a breakpoint in its destructor to find out if there was that I was creating and destroying surfaces all the time but it is just called at the beginning and at the end of the program.
Do you know what can I be possibly missing? Thanks.
soniCron
11-23-2005, 03:54 PM
If you're not familiar with SDL_RWops, check out this: http://www.kekkai.org/roger/sdl/rwops/rwops.html
However, it sounds like you are. Are you loading files in a loop, perhaps?
gringo
11-23-2005, 04:38 PM
I have just tried to take out everything... just the calculate the fps, process basic WM messages and that's all.. and in my pentium 750 that my game ran at 8 fps.. now my 'game' is just a black screen.. but it still runs at 8 fps. Also, I tried taking out SDL_HWSURFACE and SDL_DBLBUFFER (I don't remember if it is well written) but I had the same results.. I'm starting to get worried.
ggambett
11-23-2005, 04:50 PM
I have just tried to take out everything... just the calculate the fps, process basic WM messages and that's all.. and in my pentium 750 that my game ran at 8 fps..
You're obviously doing something wrong. For example, are you copying the whole back buffer to the front buffer every frame?
gringo
11-23-2005, 05:49 PM
I think I didn't understand.. I use SDL_Flip() to do that..
Isn't it the way it is supposed to be? to copy the backbuffer in every frame?
ggambett
11-23-2005, 06:04 PM
That's the officially approved way of getting 8 FPS :)
You want to blit only what has changed since the last frame. Read everyting you can find about Dirty Rectangles (commonly abreviated Dirty Rects). There has been a lot of discussion about them in the Technical forum.
gringo
11-23-2005, 06:13 PM
but... I have lots of things static.. a lot also moving.. Mostly is a match 3 with a scrolling background, but I think that the majority of the screen should be moving so I'm not sure if it is worth to calculate which areas have or have not moved.. Anyway, if this wasn't the case, for example no race game could be done decently on sdl on a pentium 750 ? Because most of the things are moving... except for the speed counter.. I'll look information on what you've said anyway, but .. I think that it should run faster in any other way too.
gringo
11-23-2005, 06:15 PM
by the way I also profiled betty's beer bar to have an idea on how fast should my game go in different areas of the code :)
The results were that the game code executed more time than SDL.dll itself .. which is clearly ideal. And the function that was bugging me, er.. I can't remember the name that I posted on the first message, it's the most used in your game too.. but with around 43% in stead of 99% like mine :(
ggambett
11-23-2005, 07:10 PM
You're correct, doing stuff with full screen scrolling backgrounds with software rendering isn't easy.
And the function that was bugging me [...] it's the most used in your game too. SDL_FreeRW? I doubt it. I'd bet it's a profiler artifact. Here's the full source of SDL_FreeRW() (src/file/SDL_rwops.c, line 294):
void SDL_FreeRW(SDL_RWops *area)
{
free(area);
}
That obviously can't take 43% of BBB's time, it wouldn't leave any CPU left for the blitting, which is of course what eats most CPU for a game like that.
gringo
11-23-2005, 11:33 PM
yes I've seen the code also .. I don't have a clue on how does SDL operates internally but believe me, according to intel's profiler, that's what take most of the time in SDL, at least in your game (in mine's! :( ) .
What I've just been discussing with a friend of mine, is that all the games we used to play in 2D that ran fast enough, had a much smaller resolution, even on neo geo emulator and stuff like that. I'm trying 800x600 .. perhaps that is what kills the performance.. The other games I worked in with resolution were under the 3D hardware layer.
I'm not sure but perhaps that is what is killing my game .. I might start considering on changing the game's resolution or migrating to PTK :)
PeterM
11-23-2005, 11:38 PM
I also don't think it's SDL_FreeRW that's using all the time (unless you're opening and closing files each frame, which would be immensely silly).
How does VTune map from address to function name? If you provided the .pdb file, or whatever, are you using the same SDL.DLL?
Obviously you can't compile SDL yourself to get a pdb file and use it with someone else's SDL.DLL.
Hope this helps,
Pete
gringo
11-23-2005, 11:40 PM
actually there's a strange issue that happens here.. once the game has ran and the profiler have to show me information, it complains that sdl.dll could not be found on the path that it actually is, and asks me to provide a new path where I re enter the same that was before and then it works.
NuriumGames
11-24-2005, 01:02 AM
but... I have lots of things static.. a lot also moving.. Mostly is a match 3 with a scrolling background
At 800x600 you need hardware acceleration or dirty rects. I think you should check some of the 2D engines that use 3D hardware. There are some of them free and you'll find information in this forums.
mahlzeit
11-24-2005, 04:26 AM
Are you locking the surfaces before blitting? If so, you shouldn't. I think in some cases (not sure) that locking a surface can make a temporary copy, which would explain the slowdown. You should also make sure your surfaces are compatible, using SDL_DisplayFormat().
ggambett
11-24-2005, 07:38 AM
You should also make sure your surfaces are compatible, using SDL_DisplayFormat().
A clarification : do that just once, when you load the surfaces.
gringo
11-24-2005, 01:10 PM
I think that this is a deeper problem than loading the surfaces.. I have just tried a blank screen on 640x480 .. I think I can't get lower than that.. Now, without loading surfaces, but making a full SDL_Flip() thus copying all the buckbuffer in every frame, I got 13/14 frames per seconds in the pentium 750 mhz I told you..
Now, I don't really understand what is happening here.. Because 640x480 would be a nice resolution to having copying all the pixels in every frame, and my 750 mhz computer used to be a nice computer where I could play lots of games.. am I missing something? or the results I am getting are ok.. Really, I must say that if that if the fps that I am supposed to get with everything running okay I have lots of things that are starting to be really weird for me.
I thought that a 2D game in 640x480 should run absolutely fast even pixel by pixel because I'm using SDL thus directx... games as StarCraft comes to my mind that could run perfectly.. lots of emulators with all the screen scrolling around that could run perfectly at 640x480.. I am pretty confused now but I think I'll start with ptk to solve my problem..
However, this issue here is something that I can't find any satisfactible answer.
PeterM
11-24-2005, 01:15 PM
If you're not doing this already, try writing the minimal app that just initialises SDL, and loops forever, polling all events then calling SDL_Flip. Not actually drawing anything.
If performance is still poor, what do you pass to SDL_SetVideoMode, and how do you handle the events?
Hope we get to the bottom of this weird problem.
Edit: Forgot to say, how are you reporting the frame rate? A decent way is to set the title bar every second (definitely not every frame).
Robert Cummings
11-24-2005, 01:15 PM
Platypus runs on a 500mhz pc at a respectable 20-30fps. It is coded in Blitzbasic and seems to flaunt all the rules.
For starters it doesn't use any dirty rects nor does it make any attempt at being clever at all. It is just brute force.
So perhaps thats something to consider...
gringo
11-24-2005, 01:18 PM
Yes but that uses the 3D card.. My point on using SDL was to be able to run the game in as much computers as possible.. without needing a 3D card.
gringo
11-24-2005, 01:20 PM
If you're not doing this already, try writing the minimal app that just initialises SDL, and loops forever, polling all events then calling SDL_Flip. Not actually drawing anything.
If performance is still poor, what do you pass to SDL_SetVideoMode, and how do you handle the events?
Hope we get to the bottom of this weird problem.
I also tried that, I got like 17000 fps something like that. It was awesome :), it's a pitty that it actually doesn't draw anything.
ggambett
11-24-2005, 01:40 PM
making a full SDL_Flip() thus copying all the buckbuffer in every frame, I got 13/14 frames per seconds in the pentium 750 mhz I told you.. [...] Now, I don't really understand what is happening here..
Well, as I said, just don't copy every pixel every frame.
PeterM
11-24-2005, 01:50 PM
I'm still not sure it should run that bad.
I was writing a 2D golf game a while back, and I went to try it on my Mum's 233MHz PII.
It ran ok - about 10-15 FPS. This was with fullscreen scrolling, alpha blending, and so on.
The only thing I'd make sure of is that as many of your surfaces are palettised (8-bit) as possible, and that you create your screen as 16 bit SDL_ANYFORMAT | SDL_SWSURFACE.
Not SDL_DOUBLEBUF or SDL_HWSURFACE, since hardware surfaces kill alpha blending, since DirectDraw doesn't support it.
And palettised, because it'll give a good speed up in terms of memory bandwidth.
wazoo
11-24-2005, 02:26 PM
What bit depth are you using in your SetVideoMode call, and what's the current bitdepth of your desktop?
gringo
11-24-2005, 02:56 PM
I fall on that too.. first of all I want to say that I am not using alpha blending at all .. I even have all my graphics in pcx to make sure of that .. I have just one moon on the sky alpha blended and that's all.. which would make no difference if I take it out.
Second, the pcx were 24 bits and I initalized the screen on 32 bits because I thought that having a 32 bits data would make things faster because of avoiding the bit masking and shifting. The problem was that in this computer (pentium 3.0!) the game worked well in windowed but a little slow in fullscreen. When I changed the window creation for 24 bits depth as the pcx, then everything started to work fine, and also in fullscreen..
Also it made me feel bad because I was thinking that a 2D game in a computer > 486 nothing matters.. I mean you can do anything and it will be as fast as you'd like. I felt somehow pathetic to had to optimize my 2d puzzle game to be able to run smoothly in my pentium 3.0.
mahlzeit
11-24-2005, 03:12 PM
My guess that it's not your computer's fault, but that you're doing something horribly wrong in the code. Without looking at the code, however, we can only make assumptions and you just end up searching for the needle in the haystack.
If you want to figure out what's wrong, then you need to approach it scientifically. Not randomly try out a bunch of things, but reduce the problem to the essentials. Use good debugging skills, in other words.
Some ideas:
1) Do other games run fine on your computer? If yes, then the problem is in your code. If no, then it's probably a botched driver or installation of DirectX.
2) Try some of the SDL example programs. Do they run at reasonable framerates?
3) Start over from a clean project. Initialize the video mode (properly!) and just blit stuff to the screen. Try to reproduce the slow framerate with the absolute minimum amount of code.
4) Learn how to use SDL. Some of the sample code out there is plain wrong and even though SDL is a very simple API, you can still easily make mistakes. Having locked surfaces while blitting, for example. Another one is having a main surface with a bitdepth that is different from the desktop's bitdepth, because SDL will create a shadow surface and this might slow things down (although this should not happen in fullscreen mode). If your surfaces don't have the same format, SDL will need to convert them before blitting, etc. These are all improper uses of the API that could lead to slow code.
5) Have fun! :-)
gringo
11-24-2005, 03:28 PM
Can I ask SDL to have two screen buffers and when it has to 'refresh' the screen in stead of copying all the pixels from one screen to the other just to change the pointer where it is pointing to, and point to the other buffer? I remember using this technique but I think that this is not what SDL does when I say SDL_Flip(..).
And the other question is .. if I have all my textures in video memory, and I my two screen buffers (the true and the copy) are in video memory, then I shouldn't be making CPU copying at all. It should be all handled by the video card. Now, if I want to make a new screen and blit the surfaces on the new screen, it should be all done in video memory, and the CPU shouldn't have to work, then, shouldn't it be as fast as using direct3d or opengl in these cases?
gringo
11-25-2005, 05:33 PM
I'd love an answer :(
ggambett
11-25-2005, 06:49 PM
This isn't the best place to learn how to program using SDL. There are lots of SDL tutorials elsewhere. The mailing list is also very active.
gringo
11-26-2005, 12:59 AM
just don't answer if you don't feel like it.
PeterM
11-26-2005, 01:44 AM
in stead of copying all the pixels from one screen to the other just to change the pointerThis is what SDL_Flip does for hardware doublebuffered (& fullscreen only) displays. It has no choice but to copy when running in a window.
As for the VRAM stuff - you're not using textures by the way, just surfaces - then you will see a speedup when using surfaces created with SDL_HWSURFACE (or SDL_DisplayFormat).
But if you start using alpha blending, it slows down to a crawl, so you've really got two options:
Use all hardware surfaces.
Create your display with SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF. 16 bits preferably.
Windowed performance will not be as good as fullscreen.
Use SDL_DisplayFormat to create converted sprites in the same format as the display.
Avoid alpha at all costs, prefer color key.Use all software surfaces.
Create your display with SDL_ANYFORMAT | SDL_SWSURFACE. 16 bits preferably.
You'll get best performance if your sprites etc are palettised.
If you can't do that (i.e. the surface is 24 bit or has alpha), use SDL_DisplayFormat and SDL_DisplayFormatAlpha.
Prefer color key palettised surfaces to alpha channelled surfaces.You'll get better answers on the SDL mailing list, since the guys there know more about the internals of SDL, whereas I don't.
Generally asking quick questions relating to performance of libraries goes down well here, but if you start to ask "how do I use library X?", or demonstrate that you really don't know how to use it, or are in over your depth, then you might be better off asking on the proper list or on gamedev.net.
Gabriel gave you very good advice, which would get your question answered better and probably faster than asking here. It's a shame you were rude to him afterwards.
You have to remember that people on message boards are not obligated to help you. If they do, they are doing it to be nice, to spread knowledge, or to stop the spread of F'd Up Data.
Pete
ggambett
11-26-2005, 09:39 AM
just don't answer if you don't feel like it. I'd do that if I was just an user. I'm also a moderator, which means I'm also concerned about keeping threads on topic and making sure the threads are relevant to the site. Since this is no longer true, I'm locking the thread. Pete said it best:
Generally asking quick questions relating to performance of libraries goes down well here, but if you start to ask "how do I use library X?", or demonstrate that you really don't know how to use it, or are in over your depth, then you might be better off asking on the proper list or on gamedev.net.
vBulletin v3.6.0, Copyright ©2000-2008, Jelsoft Enterprises Ltd.