measuring FPS

Started by
7 comments, last by frob 15 years, 9 months ago
When i measure my fps, it caps at 60 fps, which is what it is displaying at, but how do i measure the actual rendering fps, like 130 or whatever it is,. This is what I currently have for my main loop, i am using windows. This is a timer class i found, and then my main loop:

####### TIMER CLASS #######
struct ProfTimer {
   void start(void) {
      QueryPerformanceCounter(&mTimeStart);
   };
   double GetDurationInSecs(void)
   {
      QueryPerformanceCounter(&mTimeStop);
      LARGE_INTEGER freq;
      QueryPerformanceFrequency(&freq);
      double duration = (double)(mTimeStop.QuadPart-mTimeStart.QuadPart)/(double)freq.QuadPart;

	  mTimeStart=mTimeStop;
      return duration;
   }

   LARGE_INTEGER mTimeStart;
   LARGE_INTEGER mTimeStop;
};


######## my main loop ##########

bool quit=0;

ProfTimer timer;
double render_time=0.016;

timer.start();

while ( !quit )
	{
		
		// check for messages
		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )  )
		{
			
			// handle or dispatch messages
			if ( msg.message == WM_QUIT ) 
			{
				quit = TRUE;
			} 
			else 
			{
				scene->postMessage(&msg);

				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
			
		} 
		else 
		{
			
			glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
			glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );

			glLoadIdentity();
			
				scene->render();
		
			render_time=timer.GetDurationInSecs();  
			glprint(1.0/render_time,0.0,0.0);
			SwapBuffers( hDC );
			
		}
		
	}


}

Advertisement
If it's being capped at 60hz, then you've probably got V-Synch turned on, which means that SwapBuffers will actually pause to reduce the FPS to a max of 60.

Try disabling V-Sync (with code, or from your graphics driver control panel) and see if the FPS number goes higher.

E.g. For ATI cards, in Catalyst Control Center, go to 3d->All Settings->Wait for vertical refresh and set it to Always off.
would doing something like this provide accurate fps?

start_timer();
render();
end_timer();
SwapBuffers(hdc);

i am wondering because dont render commands(im using opengl) return immediately, even if the graphics card is not done rendering, which would make this show faster fps than actual if my app has a graphics card bottleneck?
Yeah, that will show you the CPU time taken to send the rendering commands to the graphics card. It might still be an interesting number, but it's not an accurate measure of FPS ;)
What Hodgman says (and you suspect) is correct. The GPU may well be busy for a while and you'll never see that, which with really optimized CPU code and a busy GPU will give you awesome frame rates which are very misleading.

If you do this instead..

end_timer();
start_timer();
render();
SwapBuffers(hdc);

.. notice end_timer is called just before start_timer now, then you'll get a proper frame rate. Well near as dammit.

You could even go further and have a CPUend_timer (where end_timer used to be), and an end_timer() as above which will give you a comparison of GPU to CPU load.

Also, don't forget there may be other system resources sucking time which will fluctuate your frame rate.
Try running a browser in the background for example. So the differential is quite handy for also monitoring any other bandwidth hogs.
Feel free to 'rate me down', especially when I prove you wrong, because it will make you feel better for a second....
thanks scratt, just what i was looking for. I think i will try that seperate cpu timer just for fun too.
actually i spoke too soon, it still says 60 fps. this seems to work tho, is this a good way to do it?

timer.start();
scene->render();
glFinish();
timer.stop();
render_timer=timer.getTimeInSeconds();
SwapBuffers(hDc);

Why not just keep a frame count, and after each second, spit it out, and reset it to zero?
As a side note, frames per second is not a very good metric.

It is generally much more useful to see the min, max, and average times.


Consider these two cases of 60 FPS:
0.00 ms min, 999.24 ms max, 16.64 ms avg
14.03 ms min, 17.91 ms max, 16.64 ms avg

And as mentioned, measure processing time, not display time. You should see something more along these lines:

1.15 ms min, 7.34 ms max, 4.21 ms avg

Generally you will see numbers much smaller for your own homebrew games. In either case, this last kind of range gives you plenty of room for other programs running on the pc.

This topic is closed to new replies.

Advertisement