Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (580)
games submitted by our members
Games in WIP (500)
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  
  problem with currentTimeMillis()  (Read 6597 times)
0 Members and 1 Guest are viewing this topic.
Offline arne

Senior Member




money is the worst drug- we should not let it rule


« Reply #30 - Posted 2005-05-25 19:46:20 »

Hi

I got a workaround with System.currentTimeMillis(), which seems to work fine: I simply count the frames and then divide the time difference by the passed number of frames.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
long timeBefore;
long timeNow;
long elapsedFrames;
while( true ) {
  timeNow = System.currentTimeMillis();
  if(timeNow == timeBefore) elapsedFrames++;
  else {
    long diffTime = timeNow-timeBefore;
    long fps = elapsedFrames/(diffTime/1000) //diffTime are millis
   elapsedFrames = 1;
    timeBefore = timeNow;
  }
}


Is this a good workaround?

Arne

:: JOODE :: Xith3d :: OdeJava ::
Offline Mark Thornton

Senior Member





« Reply #31 - Posted 2005-05-26 07:57:31 »

Quote
HotSpot just passes the given time through to through to the OS.  Nothing magical about 10msec, 15.6msec or any other number, at least not to HotSpot.


The value effects whether those calls to timeBeginPeriod/timeEndPeriod occur.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4717583
Offline sunet2000

Senior Newbie




I want my mumart account back!


« Reply #32 - Posted 2005-05-27 00:13:18 »

Quote

Before you can trust any such timing thing to be reliable you gotta run it "under load" - get a bunch of other threads running doing variable amounts of work+sleep (your AI wakes up, works for a quanta, sleeps, you decide to background load some music for the next scene, etc).  All those other threads running around will also mess with your timer's response.


Well, obviously, I designed my code to be able to handle a delay every once in a while, but when the timer is consistently late by a massive margin (in computer terms) it makes it difficult to write reliable code.

Instead of drawing a frame every 20ms and sleeping to aviod wasting cpu time, you have max out the cpu drawing frames one after another, additionally having to **guess** how long they took to draw!

Meh, I hate computers Smiley
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline sunet2000

Senior Newbie




I want my mumart account back!


« Reply #33 - Posted 2005-05-27 23:00:20 »

Quote
Hi

I got a workaround with System.currentTimeMillis(), which seems to work fine: I simply count the frames and then divide the time difference by the passed number of frames.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
long timeBefore;
long timeNow;
long elapsedFrames;
while( true ) {
  timeNow = System.currentTimeMillis();
  if(timeNow == timeBefore) elapsedFrames++;
  else {
    long diffTime = timeNow-timeBefore;
    long fps = elapsedFrames/(diffTime/1000) //diffTime are millis
   elapsedFrames = 1;
    timeBefore = timeNow;
  }
}


Is this a good workaround?

Arne



I think so, as my solution does almost exactly the same thing. It can also provide an estimate of nanosecond timing (edit - well, it does now):

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  
public class TimerTest implements Runnable {
      public void run() {
            long tstart, tend;
            long lcount = 1, nanos = 0;
            tstart = System.currentTimeMillis();
            while( true ) {

                  // Do stuff, use nanos to estimate loop time
                 for( int n = 0; n < 100000; n++ );
                  System.out.print( nanos + ", " );
                  // Stop doing stuff

                  tend = System.currentTimeMillis();
                  if( tend != tstart ) {
                        nanos = ( tend - tstart ) * 1000000 / lcount;
                        tstart = tend;
                        lcount = 0;
                  }

                  lcount++;
            }
      }

      public static void main( String[] args ) {
            new Thread( new TimerTest() ).start();
      }
}
Offline pwtenny

Innocent Bystander





« Reply #34 - Posted 2005-08-07 19:44:53 »

Well, obviously, I designed my code to be able to handle a delay every once in a while, but when the timer is consistently late by a massive margin (in computer terms) it makes it difficult to write reliable code.

Instead of drawing a frame every 20ms and sleeping to aviod wasting cpu time, you have max out the cpu drawing frames one after another, additionally having to **guess** how long they took to draw!

Right now I've created a class that uses System.nanoTimer to measure time elapsed in milliseconds like so..
Quote
// it would probably be proper Java technique to make elapsed_ms private, and use a method
// to fetch it's value, but remember this is supposed to be a high resolution timer, which means
// it should run as fast as humanly possible, which means letting outside classes access this
// field on their own.
class HighResTimer
{
   private long n1;
   private long n2;
   public long elapsed_ms;

   public HighResTimer()
   {
      n1 = 0;
      n2 = 0;
      elapsed_ms = 0;
   }

   public void start()
   {
      n1 = System.nanoTime();
   }
   
   public void stop()
   {
      n2 = System.nanoTime();
      elapsed_ms = ((n2 - n1) / 1000000L);
   }
   
        // this is the exception to my rule, so you can see how much time has gone by without stopping it..
   public long getElapsed()
   {
      n2 = System.nanoTime();
      return ((n2 - n1) / 1000000L);
   }
}

In my primary loop I have the following..

Quote
// this gives me the precise number of milliseconds of work+sleep that will give me roughly
// 30 frames per second.
long required_ms = 1000 / 30;

// two timers so I can measure how long it took for one render pass, and how long we actually
// slept afterwards.
HighResTimer renderTimer = new HighResTimer();
HighResTimer sleepTimer = new HighResTimer();

// the loop
while(true)
{
  // measure how long it took to render once...
  renderTimer.start();
  renderManager.renderScreenStuff();
  renderTimer.stop();
  // renderTimer.elapsed_ms now tells us how long it took

  // measure how long we slept (I left out the try/catch for clearity)
  sleepTimer.start();
  Thread.sleep(required_ms - renderTimer.elapsed_ms);
  sleepTimer.stop();
}

Now I don't have sleepTimer being used here because I haven't gotten that far yet since I've been spending most of my time on the renderer. Even without measuring the exact time the sleep actually took, this still keeps my engine within 2 FPS of the target 30. If you add another long above the while() loop that stores the previous passes sleep time, you can subtract that from the next sleep to compensate for it taking longer than expected. My engine has a thread for playing music and when you Thread.sleep() your main thread on purpose, it's going to lose context to the music thread and there's really no telling just how long it will run. It might take 30ms because there's a lot of disk access going on and it had to wait to read the next bit of music, or some such.

Additionally, I don't use Thread.sleep() inside the main loop, I use Util.sleep (Util being my own abstract class) that just wraps a Thread.sleep() with a few extras, such as detecting the possibility that the math I have above could quite possibly ask Thread.sleep() to sleep for 0ms, or even a negative time causing an except FPS, I don't really need to do this.

Hope this helps.
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.

xsi3rr4x (51 views)
2014-04-15 18:08:23

BurntPizza (48 views)
2014-04-15 03:46:01

UprightPath (63 views)
2014-04-14 17:39:50

UprightPath (45 views)
2014-04-14 17:35:47

Porlus (62 views)
2014-04-14 15:48:38

tom_mai78101 (86 views)
2014-04-10 04:04:31

BurntPizza (146 views)
2014-04-08 23:06:04

tom_mai78101 (243 views)
2014-04-05 13:34:39

trollwarrior1 (202 views)
2014-04-04 12:06:45

CJLetsGame (209 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
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!