Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (498)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  System.nanoTime(): good or evil?  (Read 5972 times)
0 Members and 1 Guest are viewing this topic.
Offline swallace

Junior Newbie





« Posted 2007-04-16 18:13:02 »

I've read quite a bit about System.nanoTime() in Java 1.5+, both on this forum and on the web, and here's a bit of what I've learned:

 1) nanoTime attempts to use the most precise timer available, but can only be used to measure time intervals (not walltime) -- fortunately, this is all you need in a game.

 2) I've read that nanoTime uses QueryPerformanceCounter and some have suggested that this can cause strage results on multi-core machines as well as on machines (like many laptops) that vary the clockspeed of the cpu

 3) somewhat in conflict with (2), I've also read that QueryPerformanceCounter is preferred to RDTSC (on Intel chips) since RDTSC does NOT take into account changes in clock speed (thus implying that QPC does...)

4) In a simple loops that executes System.nanoTime() and stores the result in an array, I see values as low as 1.2 micro seconds, but values as high as 5000 micro seconds if I run the loop for 10000 iterations or so.  Some people have noted that varying the clock speed of the CPU can cause discontinuities in the results of nanoTime(), so perhaps that explains the results, but it could also presumably be due to the OS running other processes.

The bottom line is: is there any consensus as to whether System.nanoTime() is good or evil? If evil, is there a suggested alternative timer?

Offline Jeff

JGO Coder




Got any cats?


« Reply #1 - Posted 2007-04-16 18:52:09 »

If you need that level of accuracy in timing then its good.

As for what it exactly does underneath, thats platform dependent but if you see it actually create wrong results and you can reproduce it, you should bug report it.

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #2 - Posted 2007-04-16 19:15:52 »

QPC is pretty fragile. TGT is way more robust. However, its resolution is "only" 1msec.

LWJGL's timer uses TGT on Windows (and currentTimeMillis elsewhere, because that already gives you a 1msec res on mac/linux).

弾幕 ☆ @mahonnaiseblog
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Markus_Persson

JGO Wizard


Medals: 15
Projects: 19


Mojang Specifications


« Reply #3 - Posted 2007-04-17 08:17:53 »

If you need that level of accuracy in timing then its good.

As for what it exactly does underneath, thats platform dependent but if you see it actually create wrong results and you can reproduce it, you should bug report it.

It's extremely trivial to reproduce. Use it on a dual core amd processor. After a while, the returned value starts diverging more and more as it retrieves it from a random core.

It basically makes the method totally worthless.

Play Minecraft!
Offline Jeff

JGO Coder




Got any cats?


« Reply #4 - Posted 2007-04-17 20:11:32 »

Has this been bug reported with the example? And is it a question of nanoTime not functioning properl, or Windows not functioning properly?

I wouldnt call it totally worthless in any case as I\\\'m using it quite successfully in my BHO client at the moment.  Ofcourse I\\\'m only using it for split second timing.  Timing in lower resolutions I do with System.currentTime Millis.

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 799
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #5 - Posted 2007-04-17 20:54:39 »

You could try to correct the diverging values a bit, although it won't be extremely fast...

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
public class Clock
{
   private static final long max_difference_in_ns = 25L * 1000000L; // must be fairly high (Win98=55ms -> 120ms, WinXP=10ms -> 25ms)
  private static final long started_in_ms;
   private static final long started_in_ns;
   private static long correction_in_ns = 0L;

   static
   {
      started_in_ms = System.currentTimeMillis();
      started_in_ns = System.nanoTime();
   }

   public static final long nanoTime()
   {
      long elapsed_in_ns = System.nanoTime() - started_in_ns;
      long elapsed_in_ms = System.currentTimeMillis() - started_in_ms;

      long difference_in_ns = (elapsed_in_ms * 1000000L) - (elapsed_in_ns);

 // converge with factor 0.15

      if(difference_in_ns > max_difference_in_ns)
         correction_in_ns += difference_in_ns * 15 / 100;
      else if(difference_in_ns < -max_difference_in_ns)
         correction_in_ns -= difference_in_ns * 15 / 100;

      return correction_in_ns + elapsed_in_ns;
   }

   public static final long getTimingErrorNanos()
   {
      long elapsed_in_ns = System.nanoTime() - started_in_ns;
      long elapsed_in_ms = System.currentTimeMillis() - started_in_ms;

      return (elapsed_in_ms * 1000000L) - elapsed_in_ns;
   }

   public static final long getTimingCorrectionNanos()
   {
      return correction_in_ns;
   }
}

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Markus_Persson

JGO Wizard


Medals: 15
Projects: 19


Mojang Specifications


« Reply #6 - Posted 2007-04-18 10:08:29 »

Has this been bug reported with the example? And is it a question of nanoTime not functioning properl, or Windows not functioning properly?

Unfortunately, I'm far too lazy and selfish to report it. Wink

Dual core AMDs does something nasty with the timing. It's a well known issue. Some games (painkiller, for example) won't run at all unless you disable one core for them, and nanoTime works horribly bad unless you disable one core.
AMD, of course, claims it's not a bug. People who depend on the timing the way they do are the people who get it wrong, but they did release a "fix" for it that's basically just a program that synchronizes the timers every now and then.

The source code (scroll down) for my Infinite Mario Bros game contains a pretty bad work around for the bug after detecting it (ie after time has gone BACKWARDS once, as it does with nanoTime)

Play Minecraft!
Offline princec

JGO Kernel


Medals: 378
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #7 - Posted 2007-04-18 13:23:16 »

Hm it has occurred to me that you should be able to detect the divergence and start tracking two sets of values if you're clever... but then again, who needs more than 1ms accuracy anyway?

Cas Smiley

Offline Markus_Persson

JGO Wizard


Medals: 15
Projects: 19


Mojang Specifications


« Reply #8 - Posted 2007-04-19 07:54:34 »

Hm it has occurred to me that you should be able to detect the divergence and start tracking two sets of values if you're clever... but then again, who needs more than 1ms accuracy anyway?

Cas Smiley

How would you know which one you read?

Play Minecraft!
Offline emzic

Senior Member





« Reply #9 - Posted 2007-04-23 13:32:14 »

It's extremely trivial to reproduce. Use it on a dual core amd processor. After a while, the returned value starts diverging more and more as it retrieves it from a random core.

but you usually query the time on the gameloop-thread.
and shouldnt one thread stay on the same core usually?

www.embege.com - personal website
webstart blendinspect - OpenGL BlendingModes visualization.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Kova

Senior Member





« Reply #10 - Posted 2007-04-23 22:53:45 »

I know nothing about dual core CPUs, but I can imagine software knows nothing about them having 2 cores... CPU just feeds data back the same way as normal ones. Again, this is only a assumption, as if there were difference new software should be written just for them.
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #11 - Posted 2007-04-24 05:12:23 »

but you usually query the time on the gameloop-thread.
and shouldnt one thread stay on the same core usually?
no, not unless you set thread affinity - which you dont.

Offline fletchergames

Senior Member





« Reply #12 - Posted 2007-04-24 16:46:19 »

After reading this topic, I switched from System.nanoTime() to System.currentTimeMillis(), and my game runs alot smoother.

So, yes, System.nanoTime() is evil.
Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #13 - Posted 2007-04-24 22:19:51 »

Note that the resolution of currentTimeMillis depends on the OS.
-win9x 50-55msec
-nt/2k/xp 10msec
-linux/mac 1msec

弾幕 ☆ @mahonnaiseblog
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #14 - Posted 2007-04-25 08:10:00 »

Heh, we've been whining for years for a high precision timer, and now it turns out to be evil.

I preferrably use LWJGL's timer. You get 1ms precision regardless of OS and it just works.

Quote
-win9x 50-55msec
I've never seen such low precision on win9x, I always got about 10 ms precision on win98.

Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #15 - Posted 2007-04-25 11:23:35 »

I always got 50-55msec on win98se.

However, you can sleep() less than that.

And I also prefer lwjgl's timer. Wink

弾幕 ☆ @mahonnaiseblog
Offline JAW

Senior Member


Medals: 2



« Reply #16 - Posted 2007-04-25 14:50:10 »

nanoTime() seems to be a far better option than currentTimeMillis(), at least on Windows. As mentioned above, on Windows the Timer has a 50 ms resolution, far too less for games. But I never ran nanoTime() for a long time or on other PCs with AMD or somewhat. So it might have its drawbacks.

Regarding other timers, I am using 2D only and no GL or such stuff, can you suggest any timer to use? Or is the LWJGL Timer independent from 3D rendering?

-JAW
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #17 - Posted 2007-04-25 17:15:24 »

Quote
As mentioned above, on Windows the Timer has a 50 ms resolution...
That is, if you are running an ancient version of Windows which hardly anyone uses anymore. I myself never experienced timing resolutions that low, even on Win98 (which doesn't mean no Win9x installation has timing resolutions that bad, though).

Quote
Regarding other timers, I am using 2D only and no GL or such stuff, can you suggest any timer to use? Or is the LWJGL Timer independent from 3D rendering?
I don't think the LWJGL timer depends on OpenGL usage, but it seems to be a bit of overkill to use LWJGL only for its timer.
Why not use Slick too while you're at it, if you need a good timer and the benefits of OpenGL combined with easy to use 2D rendering?  Smiley

Offline JAW

Senior Member


Medals: 2



« Reply #18 - Posted 2007-04-26 06:36:56 »

I have measured currentTimeMillis() being 50 - 55 ms on Windows XP. Maybe it depends on some hardware like mainboard or processor. Maybe its just with Intel processors, or AMD, or such. I cant tell. But I am sure a lot of XP users can copy that currentTimeMillis performs poor on XP.

Or is it a Java 5 problem? Do you use the newest Version?

-JAW
Offline CaptainJester

JGO Knight


Medals: 12
Projects: 2
Exp: 14 years


Make it work; make it better.


« Reply #19 - Posted 2007-04-26 11:21:48 »

I use XP pro and have a resolution of 20ms.

Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #20 - Posted 2007-04-26 12:45:47 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
public class MRes{
   public static void main(String[]args){
      long smallestDelta=Long.MAX_VALUE;
      long start=System.currentTimeMillis();
      long current=start;
      long last=start;
      long delta;
      System.out.println("testing...");
      while(current-start<5000){
         current=System.currentTimeMillis();
         delta=current-last;
         if(delta!=0&&delta<smallestDelta)
            smallestDelta=delta;
         last=current;
      }
      System.out.println(System.getProperty("os.name")+" ["+
         System.getProperty("os.version")+"]["+System.getProperty("os.arch")+"]"
      );
      System.out.println("smallest delta: "+smallestDelta+"msec");
   }
}


gives me:
1  
2  
3  
testing...
Windows 2000 [5.0][x86]
smallest delta: 10msec

弾幕 ☆ @mahonnaiseblog
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #21 - Posted 2007-04-26 13:14:34 »

testing...
Windows XP [5.1][x86]
smallest delta: 15msec

testing...
Mac OS X [10.4.9][i386]
smallest delta: 1msec

Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #22 - Posted 2007-04-26 13:19:29 »

The Mac result was as expected. The XP one really baffles me tho.

弾幕 ☆ @mahonnaiseblog
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #23 - Posted 2007-04-26 14:40:04 »

Same here:

testing...
Windows XP [5.1][x86]
smallest delta: 15msec

Offline moogie

JGO Knight


Medals: 12
Projects: 6
Exp: 10 years


Java games rock!


« Reply #24 - Posted 2007-04-26 22:59:24 »

and here as well:

testing...
Windows XP [5.1][x86]
smallest delta: 15msec
Offline ryanm

Senior Member


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #25 - Posted 2007-04-27 08:45:06 »

1  
2  
3  
testing...
Linux [2.6.20-15-generic][i386]
smallest delta: 1msec

Hippies are good at some things I suppose...
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #26 - Posted 2007-04-27 09:04:56 »

Does anybody know why currentTimeMillis on Windows is so rough?

Maybe we should submit an enhancement request to have 1ms precision on Windows too (it's not a bug since currentTimeMillis doesn't guarantee anything).

Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #27 - Posted 2007-04-27 10:00:19 »

>Does anybody know why currentTimeMillis on Windows is so rough?

It uses the OS' tick counter, whose resolution depends on the OS.

Here is some overview:
http://www.gamedev.net/reference/programming/features/timing/

As you can see TGT has (had?) a few issues, too. However, QPC has a lot more.

弾幕 ☆ @mahonnaiseblog
Offline JAW

Senior Member


Medals: 2



« Reply #28 - Posted 2007-05-04 13:03:41 »

Do you have any useful test to verify nanoTime() ?
When I used nanoTime, it always worked out well, but I never ran more than a few seconds. I dont know if it can
make trouble when running for minutes / hours, if it has temporary errors or so.

-JAW
Offline Kova

Senior Member





« Reply #29 - Posted 2007-05-04 13:49:27 »

When I used nanoTime, it always worked out well, but I never ran more than a few seconds. I dont know if it can
make trouble when running for minutes / hours, if it has temporary errors or so.

did you read the whole thread? you realize that it's only a problem on multi-core cpus? Sorry if you are talking about them, I got impression that you aren't.
Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

BurntPizza (17 views)
2014-09-21 02:42:18

BurntPizza (13 views)
2014-09-21 01:30:30

moogie (13 views)
2014-09-21 00:26:15

UprightPath (24 views)
2014-09-20 20:14:06

BurntPizza (27 views)
2014-09-19 03:14:18

Dwinin (40 views)
2014-09-12 09:08:26

Norakomi (71 views)
2014-09-10 13:57:51

TehJavaDev (96 views)
2014-09-10 06:39:09

Tekkerue (49 views)
2014-09-09 02:24:56

mitcheeb (70 views)
2014-09-08 06:06:29
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!