Sign in to follow this  
Kryptyglyf

Is this what you'd expect to happen?

Recommended Posts

My frame rate drops from ~100fps to 10fps when I call an empty function once for each pixel in a 640x480 screen.
static void function_to_call(void)
{
}

static void copy_to_screen(SDL_Surface* surface, int width, int height)
{
        SDL_LockSurface(surface);
	for (y = 0; y < height; y++)
	{
		for (x = 0; x < width; x++)
		{
			function_to_call();
		}
	}
        SDL_UnlockSurface(surface);
        SDL_UpdateRect(surface, 0, 0, 0, 0);
}
copy_to_screen() is called continuously within the message loop. When I comment out the function_to_call() line, the frame rate is ~100fps. When it isn't commented out, the frame rate drops to ~10fps. Is that kind of drop what you'd expect on a Pentium M 2.0GHz? That amount of drop seems a bit extreme to me. [Edited by - Kryptyglyf on March 9, 2007 9:12:04 PM]

Share this post


Link to post
Share on other sites
I'm going to take a stab in the dark and say that the loop itself is being optimized out by the compiler when it sees that it does nothing.

Share this post


Link to post
Share on other sites
Even when calling an empty function, your computer still needs to iterate through 307,200 (640 pixels times 480 pixels) separate function calls each frame. Is it necessary to be checking each pixel individually like this?

Share this post


Link to post
Share on other sites
Quote:
Original post by SirSmokey
I'm going to take a stab in the dark and say that the loop itself is being optimized out by the compiler when it sees that it does nothing.


I don't know about other compilers, but I know that VC++ does that in release mode. I had this problem when doing some performance testing - looping a function I wrote 1,000,000 times. When VC++ saw that the loop doesn't actually affect anything (no variables changed, no output), it just threw away the entire loop.

Share this post


Link to post
Share on other sites
The compiler definitely isn't removing the function call. The frame rate is high when the function is commented out and significantly lower when it isn't commented out.

I was going to do some lighting calculations on each pixel with that function, but if this amount of slow down is to be expected from just calling an empty function, I don't think I'm going to have the processing power to do lighting calculations. Sort of why I'm asking if this degree of bog down is reasonable to expect is to determine if I should continue to pursue the lighting functionality at all or at least pare it down significantly.

I just found it a little unbelievable that the frame rate went down THAT much. I would have expected maybe a 40% or 50% drop at most, but not 90%.

Share this post


Link to post
Share on other sites
Hey there.

I would imagine this is a problem

static void copy_to_screen(SDL_Surface* surface, int height, int height)

parsing in "height" TWICE !!!
(Does this actually compile ??)

your for loop wont be doing much either, since "width" was never assigned

for (x = 0; x < width; x++)


As "width" is unassigned, it could be some massively high number also.
so you could be causing a massive loop, hence the drop in frame rate

;-)

Share this post


Link to post
Share on other sites
LOL! Damn typos!

It is actually correct in the source file, I just copied it wrong to the forum. :o

I can confirm that the width and height are correct in the debugger.

Thanks though. :)

Share this post


Link to post
Share on other sites
Hi again,

OK glad thats ok.

The only question I have then, is why the need for a function that does nothing ????

if you want to test it, just make the function do something, even if it's pointless, just declare a variable and assign is something.

static void function_to_call(void)
{
int i = 0;
}


... and personally I would specify that your loops are integers
(depending on your compiler)

for (int y = 0; ....

Share this post


Link to post
Share on other sites
Quote:
Original post by Kryptyglyf
The compiler definitely isn't removing the function call. The frame rate is high when the function is commented out and significantly lower when it isn't commented out.


Well what I meant was that when you comment out the function call, the compiler sees that inside the loop, nothing happens (no function call or anything) so it might remove the loop eniterly.

But if your in debug mode, then no optimizations should be happening... i think.

Share this post


Link to post
Share on other sites
I inserted:


int i;
i = 0;
i++;


and that took another frame off the frame rate. 11ms adding two instructions to the loop?

I don't need a function that does nothing. I actually had a function that did some lighting calculations, but the app was running at like 2fps so I started eliminating stuff to narrow down what was creating the hang up. It turned out to be a function inside the x,y loop. When I removed the function from the loop, the frame rate shot up to 100+fps, with the function ~7-8fps. So I started commenting out code in that function until there was nothing left but variable declarations only to find that I'm still running ~10fps. Then I created function_to_call(), had the same problem, played around with __fastcall, __inline, etc., scratched my head some, then posted here.

Share this post


Link to post
Share on other sites
You gotta remember that calling a function makes the stack grow and other things.

Remember 2Ghz is dedicated to your entire system not just your one application. Windows constantly grabs different programs to run and switches back and forth. Not only does that take up some of those 2Ghz, but it also has to store specific program data each time, eating up more of the 2Ghz.

Share this post


Link to post
Share on other sites
hhmmm strange ** scratches head also **

Does the app actually seem slow, is it jerky, does your mouse pause etc etc..

Or is this just an impression given by your FPS.

maybe you could have a problem with the FPS calculation somewhere.

Also do you calculate your FPS in the DrawScene() or main loop.

I know it's a stab in the dark, but I had FPS issues, when calculating it during DrawScene()
(or what ever your render scene function is called !)

So I moved it into the main loop, after reading another thread and it solved many problems

Share this post


Link to post
Share on other sites
Quote:
Original post by SirSmokey

Well what I meant was that when you comment out the function call, the compiler sees that inside the loop, nothing happens (no function call or anything) so it might remove the loop eniterly.

But if your in debug mode, then no optimizations should be happening... i think.


Ah, that makes sense. :)

I added

i = 0


outside the loop. Then

i = x % 3 ? i << 2 : i + 1;

inside the loop. Then

x = i;

outside the loop, hoping to 'detrigger' any optimization. The frame rate dropped to ~20fps.

hmmm, maybe I am asking too much from the hardware.

Share this post


Link to post
Share on other sites
I doubt you are asking to much from the hardware.

I would say that was a very simple calculation for a computer, plus you are not actually telling it to do any additonal rendering.

Plus you are practically using the lowest possible resolution of 640x480.
Not knowing your complete hardware spec, but I doubt what you are doing should have such an effect !

Just try something simple and rule out the external function call.

ie.....

change
for (x = 0; x < width; x++)
{
function_to_call();
}

TO


int i =0;

for (x = 0; x < width; x++)
{
i = x;
}

Just so your loop is doing something, and rule out the externals.
should pin-point the problem area, although I can't really see anything wrong with the code.

I know you said it was a typo earlier, maybe you could copy and paste the code again, just so we can see 'exactly' what you have ;-)

Share this post


Link to post
Share on other sites
Quote:
Original post by darren_mfuk
hhmmm strange ** scratches head also **

Does the app actually seem slow, is it jerky, does your mouse pause etc etc..

Yes.

Quote:
Original post by darren_mfuk
Or is this just an impression given by your FPS.

maybe you could have a problem with the FPS calculation somewhere.

Also do you calculate your FPS in the DrawScene() or main loop.

I know it's a stab in the dark, but I had FPS issues, when calculating it during DrawScene()
(or what ever your render scene function is called !)

So I moved it into the main loop, after reading another thread and it solved many problems


The frame rate is calculated in the main loop.


while (...)
{
copy_to_screen(surface, width, height);

ticks = GetTickCount();
fps = 1000.0 / (float)(ticks - last_ticks);
last_ticks = GetTickCount();
}


That isn't the exact code, but the basic idea.


Share this post


Link to post
Share on other sites
Quote:

Just try something simple and rule out the external function call.

ie.....

...

Just so your loop is doing something, and rule out the externals.
should pin-point the problem area, although I can't really see anything wrong with the code.

That's what I did with the previous
			i = x % 3 ? i << 2 : i + 1; 

line.

Quote:

I know you said it was a typo earlier, maybe you could copy and paste the code again, just so we can see 'exactly' what you have ;-)

Well you can't say you didn't ask for it!!!!
[source lang=C]
static void function_to_call(void)
{
}

static void CopyToScreen(SDL_Surface* pSurface, TEuint* pixels, TEuint width, TEuint height)
{
// pixels have the format 0xRRGGBBAAu
TEuint x, y;
TEuint i;
// SDL_Color c;

// TEuint p;

// c.r = (Uint8)(0xFFu);
// c.g = (Uint8)(0xFFu);
// c.b = (Uint8)(0xFFu);

// p = 0xFFFFFFFFu;
i = 0;

SDL_LockSurface ( pSurface );
# if 1
for (y = 0; y &lt; height; y++)
{
for (x = 0; x &lt; width; x++)
{
// p = pixels[y*width+x];
// c.r = (Uint8)((p & 0xFF000000u) &gt;&gt; 24);
// c.g = (Uint8)((p & 0x00FF0000u) &gt;&gt; 16);
// c.b = (Uint8)((p & 0x0000FF00u) &gt;&gt; 8);
// c.a = (Uint8)(p & 0x000000FFu);

/*i = i + x &lt;&lt; 2*/ i = x % 3 ? i &lt;&lt; 2 : i + 1;//
;
// function_to_call();
// SetSDLPixel(pSurface, x, y, c);
}
}
// x = i;
# endif
SDL_UnlockSurface ( pSurface );

SDL_UpdateRect ( pSurface , 0 , 0 , 0 , 0 );
}
TEdllapi TEvoid TEvideo_BlastScreen(TEvoid)
{
TEuint width, height, bpp;
TEuint* pixels;
TEsint* normals;
TEuint i, j;


translate_mode(Mode, &width, &height, &bpp);

pixels = TEDBcolor_GetBuffer(ScreenColors);
normals = TEDBnormal_GetBuffer(ScreenNormals);
#if 0
j = 0;
for (i = 0; i &lt; width*height; i++)
{
pixels[i] = get_pixel_color(pixels[i], normals[j], normals[j+1], normals[j+2]);
j+= 3;
}
#endif

[b]CopyToScreen(SDLScreenData.Screen, pixels, width, height);[/b]
}

/* ************************************************************* */
/* IN MAIN FUNCTION */
while (TE_PumpMessages())
{
// TEvideo_ClearScreen();
// TEvideo_BltScreen(cb, nb, x, y, w, h);
if (x+inc &gt;= 640-w)
inc = -inc;
if (y+inc &gt;= 480-h)
inc = -inc;
x+=inc;
y+=inc;

[b]TEvideo_BlastScreen();[/b]

ticks = GetTickCount();

fps = (float)(ticks-last_tick_count);

fps = 1000.0f / fps;

fprintf(c_file, "%f\n", fps);

last_tick_count = GetTickCount();
}



[Edited by - Kryptyglyf on March 9, 2007 10:13:53 PM]

Share this post


Link to post
Share on other sites
hey,

just a tip ;-)
check this link
http://www.gamedev.net/community/forums/faq.asp#tags

I know they are starting to ban people for posting huge amounts of code.
I know I asked for it lol, but be warned.


ok I don't see anything that really springs out here.

TEdllapi TEvoid TEvideo_BlastScreen(TEvoid)
{
TEuint width, height, bpp;
TEuint* pixels;
TEsint* normals;
TEuint i, j;


translate_mode(Mode, &width, &height, &bpp);

pixels = TEDBcolor_GetBuffer(ScreenColors);
normals = TEDBnormal_GetBuffer(ScreenNormals);
#if 0
j = 0;
for (i = 0; i < width*height; i++)
{
pixels[i] = get_pixel_color(pixels[i], normals[j], normals[j+1], normals[j+2]);
j+= 3;
}
#endif

CopyToScreen(SDLScreenData.Screen, pixels, width, height);
}



Not sure what translate_mode(Mode, &width, &height, &bpp); does.
But I don't actually see where you are assigning width & height.
I see it declared but never assigned before calling CopyToScreen()

Share this post


Link to post
Share on other sites
Thanks for the link. It would have been nice if there was a link for it in the reply page.:)

translate_mode() gets the height, width, and bpp of Mode. It was basically an idiotic hack I put in there for some reason I don't remember. I needed the height and width of the screen but for some reason didn't want to store the height and width explicitly. It's basically just a switch statement that fills in the width, height, and bpp.

Well, I've got to be getting to bed, thanks for the help. I'll pick this back up tomorrow.

Share this post


Link to post
Share on other sites
That's the only point I see a problem for in the code so far.

maybe pop a messagebox in there or << cout....
so you know you have got the right height and width.

looks like you are parsing height & width TO translate_mode() .. but how are you returning it FROM, for those local variables ?


Quote:
Original post by Kryptyglyf
It was basically an idiotic hack I put in there for some reason I don't remember.


// Comments are your best friend
// you'll forget half of what your code does in a months time

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this