Gamer Timers and Animation Loops

Hello everyone, I have a question which i have seen asked a few times on this and other forums but I cant seem to find a good answer for it!

I want to use a higher resultion timer or clock reading method with a better granularity than that of System.currentTimeMillis(), I have seen the use
of System.nanoTime() recommended a few places, but have also read that it has problems when using multi core (usually athlon) systems, which can lead to useless results. Does anyone know the scale of this error, a few nanoseconds here and there wouldnt bother me at all, but if it is really inaccurate then i wouldnt be able to use it.

Is their a better alternitive?

I just really want it for measuring my FPS and UPS in my game accuralty to achive a consistant UPS, any help or info would be much appreciated!

Thanks ???

Hi!

I’m calculating the FPS from the nanoTime()-Value, but only after a number of frames have been drawn and a minimum amount of time elapsed.

The FPS value changes quite frequently - it is difficult to adjust the game speed to it without having occasionally things “bumping” and “hopping” around… So I calculate a smoothed FPS value as well: smoothFPS.

`
numFrames++;

final long now = System.nanoTime();

// 1 nanosecond = 1e-9 seconds
// 1 microsecond = 1e-6 seconds = 1e3 * nanoseconds
// 1 millisecond = 1e-3 seconds = 1e6 * nanoseconds

// Only update the FPS value if enough happend in the meantime
if ( now-lastTime > 1e7 && numFrames>10 ) {
// Enough time or frames since last update - now calculate the new FPS value
fps = numFrames * 1000.0f / ((now-lastTime)/1000000.0f);
numFrames=0;
lastTime = now;

// Smooth the FPS over the last 200 frames...
smoothFPS = 199.0f/200.0f * smoothFPS + 1.0f/200.0f * fps;

}
`

Greetings
Stefan

Hello, thanks for you reply, you dont comment on the nanoTime() reliability, that was specifically what my post was regarding, of what should be used instead of it because of the multiple processor issue! :slight_smile:

Oh yes, sorry…

I did not ran into any problems with nanoTime yet. My approach was tested on single, dual- and quad-core Intel machines without any problems. (but no testing on Athlons was performed yet)

Having around 1000 FPS on the quad-core machine, the timing is still very accurate in the way that the gameplay feeling gives no indications that a timer resolution problem exists.

Greetings
Stefan

excellent, thanks for the insight! 1000fps is pretty hefty, i imagine it’s a typo :stuck_out_tongue:

Ill have another look into it, thanks!

Hi,

I wrote up my tests on java timers. You can find the whole article here.

The bottom line is that to be semi accurate, given the bugs and OS conflicts, you have to be off multiples of 10 like 11, 21, 32, etc. It can’t be 10, 20, 30. Milliseconds is just as good as if not better than nano or even third party as long as you set it up correctly.

I hope it helps.

Darrin

LWJGL’s timer is the most robust one. It’s TGT (time get time) with a resolution of 1msec. On Linux and Mac currentTimeMillis is used under the hood, which also results in a resolution of 1msec.

nanoTime uses QPC (query performance counter), which has some issues on some machines.

On my old 500mhz machine I got so called QPC-leaping, which basically means that the timer will randomly jump a few seconds into the future whenever there is some bus load. With the Nvidia graphics card everything was fine, but the ATI one triggered the issue for reasons unknown to me. I guess it either caused more bus load or the usage pattern was different. (Using nanoTime in command line programs worked fine for example.)

Well, that’s just one of the QPC issues. IIRC there are like 5 different ones. TGT on the other hand only got one problem (IIRC), which only occurs on some 20-25 year old mainboards. So yea, it’s a rather robust timer.

in some case it may be practical to achieve smart UPS using a low granularity timer as System.currentTimeMillis() and an uncontrolled FPS loop.

logic is only updated when a new frame is being rendered


	
	
private long gameLogicLastTime=-1;
	
//Logic update rate = 10 ms
private long gameLogicRate=10;


//Your main rendering Thread
public void run()
{
	//Uncontrolled FPS loop
	while(this.mustRun)
	{
		this.doLogic();	
		this.diplay();
		Thread.yield();
	}
}

//Perform game logic for elapsed time
public void doLogic()
{
	long time=System.currentTimeMillis()
	
	//First call ?
	if(this.gameLogicLastTime==-1)
	{
		this.gameLogicLastTime=time;
		return;
	}
	
	//Compute elapsed time since last game logic
	long elapsedTime=time-this.gameLogicLastTime;
	
	
	//If elapsed time lower than logic rate return
	if(elapsedTime<this.gameLogicRate)
		return;
		
	
	//Compute number of game logics to perform	
	int nbGameLogic=(int)(elapsedTime/this.gameLogicRate);


	for(int gameLogicCount=0;gameLogicCount<nbGameLogic;gameLogicCount++)		
		this.doLogicOnce();	
	
	this.gameLogicLastTime+=nbGameLogic*this.gameLogicRate;		
}

//Perform game logic for 10 ms (gameLogicRate)
public void doLogicOnce()
{

}	

//Render game graphics
public void display()
{

}


Aha, good to know there is something out there which can work, i was gettting worried. I was trying to find it for an applet, but i am not famililiar with the LWJGL, it seems it might not be the easiest thing to use with applets (but i could be wrong, ill have to have a read)

Anyone know off hand if pulpcore implements any good useable timers

in java 1.4+
there is the un documented timer



import sun.misc.Perf;

 public static long getTime() {
  return  p.highResCounter();
 }
  
 private static Perf p = Perf.getPerf();
 public static long sync(int fps, long timeThen) {
  long gapTo =  p.highResFrequency() / fps + timeThen;
  long timeNow = p.highResCounter();
		
  while (gapTo > timeNow) {
   try {
    Thread.sleep(1);
   } catch (InterruptedException e) {}
   timeNow = p.highResCounter();
  }
  return timeNow;
 }


long timeThen =  p.highResCounter(); //init call


timeThen = sync(fps, timeThen); //sync call (I personally set fps = 60)

and the best one you can get with the default api 1.5+ is nanoTime()

This code doesnt really measure FPS like you want. It will just cap the game speed to a disired frame rate.

If you would like source code of how to make an LWJGL sync timer without having to make a call to Display creat just ask, but LWJGL needs to be signed for applets so its not that user friendly.

No, user friendly is always key!

Anyone know off their head how the pulpcores platform specific calls to CoreSystem.getTimeMillis() and getTimeMicros are implmented?

Isnt it a risk using sun.misc.Perf as it could be removed in a newer java version?

its possible to implement multiple methods, and check the java version at runtime.

sun.misc.Perf uses the same timer as nanoTime(), so it will have the same problems. I had a problem with TGT in LWJLG where the resolution degraded to around 15ms in some situations. This was on a 6-7 year old computer.

I don’t think there is a timer that works on all computer. The best solution would be to do an analysis when the app start and select the best time. Should find some c code that does this if you google.