Jump to content

  • Log In with Google      Sign In   
  • Create Account


[java] Getting accurate time


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 snowmoon   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 2000 - 02:34 AM

Hello all, I have been using System.currentTimeMillis() to do some timing, but it appears to be horrible for fine grain timing. Is there any better methods to do timing? I need to be able to time down to 1/30 of a second fairly accuratly. I''m timing screen drawing routines. Thanks in advance. Snowmoon

Sponsor:

#2 c_wraith   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 2000 - 04:28 AM

There''s nothing better than System.currentTimeMillis() in the standard java libraries. You''d need some timing library written using JNI to do better, and I don''t know of any, although I haven''t looked.

The problem with System.currentTimeMillis(), though, is actually restricted to PC''s. Using Sparc machines, I''ve gotten 1 ms granularities, although I haven''t done testing for accuracy (nor do I even know how). The problem with that function on PC''s is that it measures clock ticks, which only happen 18.2 times per second... That makes the finest possible granularity slightly more than 50 ms.

#3 felonius   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 2000 - 05:41 AM

It is correct that the PC only send interrupts 18 times per second, but this default can be changed by reprogramming the Timer chip via JNI and accessing it via JNI.

But the internal CPU timer runs with millisecond granularity and can be read with the C call clock(). The exact granularity is seen in the macro CLOCKS_PER_SEC.

Make a JNI fucntion that calls clock and you have your solution.

Jacob Marner

#4 Wrathnut   Members   -  Reputation: 358

Like
Likes
Like

Posted 17 November 2000 - 05:47 AM

I have a similar problem.. I have been using the System.currentTimeMillis(); to try and get an accurate Frames per Second count.. And as far as I can see it does even work at all..
What I did was setup 2 variable currentTime and lastTime, these get the System.currentTimeMillis(); value applied to it. That is to say:

currentTime = System.currentTimeMillis();

do drawing, and game routines;

lastTime = currentTime;

currentTime = System.currentTimeMillis();

FPS = (currentTime - lastTime)/1000;


Now as far as I can figure this should be right but it seems that when I try and do some stuff to the game engine that obviously drops the FPS from what I can see, the actual values of FPS remain about the same.. I.E. I''ve been getting about 25 fps even when I know for a fact I''m getting less than 10... Is there something wrong with the routine I''m using for FPS or is it just the System.currentTimeMillis() function? Any help woul be greatly appreciated.

War doesn''t determine who is right, war determines who is left.

#5 snowmoon   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 2000 - 06:05 AM

I was using an almost identicle timing loop and getting innacurate results too.

That is the exact same behavior that I am seeing. I was thinking of using another thread to do the time calcualations based on a frame count. Every paint increments the frame count and the other thread counts waits 10 frames and then does a calculation in a seperate thread and output''s that to a debug window or system.out

Part of the problem as I can see is that just timing paint is not enough because there are other things that happen in the backgroung before and after paint that will cause things to slow down.

If you want to discus this further you can reach me off list eric at snowmoon dot com .

Once I have figured it out I''ll let everyone know.

This is frustrating because I wanted a routine to draw as many things on the screen as possible during my 1/30''th of a second window, but with the time only firing 18 times a secone that doesn''t work right.

One possible solution I''ll try tonight is using a alarm thread. Something that just sits on a mutex and when it gets called it will sleep a specific ammount of time and then throw a conditional varibale or something. This is assuming that the Thread.sleep(long) and (long,long) are more accurate than System.currentTimeMillis(). This still does not solve the short timing issue.



#6 GKW   Members   -  Reputation: 200

Like
Likes
Like

Posted 17 November 2000 - 08:23 AM

The thread idea is acctually in a couple books I have and they say it is not that accurate because you can''t tell it to wake up in exactly 5 ms. It is approxamatly 5 ms. The microsecond timer that comes with the Magician package game me these results on an animation loop:

System: 32 ms
MicroTimer: 31.312 ms
Sys: 31 ms
MT: 31.589 ms
Sys: 31 ms
MT: 33.066 ms
Sys: 31 ms
MT: 30.618 ms
Sys: 31 ms
MT: 30.756 ms
Sys: 32 ms
MT: 30.978 ms

I just don''t think that going through JNI is going to give you an accurate time.

I wanrned you! Didn''t I warn you?! That colored chalk was forged by Lucifer himself!

#7 snowmoon   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 2000 - 08:41 AM

I just want ~timing. I don''t need it to wake up in exactly 33.2345 microseconds. I just want to be able to time things to ~25-30 microseconds. Sys.currTimeMills under windows can only do increments of 40-50 so it''s useless for the most part.

And what is MicroTimer? What platform are you on?

#8 GKW   Members   -  Reputation: 200

Like
Likes
Like

Posted 17 November 2000 - 07:51 PM

I was not suggesting that you need microsecond granularity. I was suggesting that any call through jni is not going to be much better than System.currentTimeMillis(). MicroTimer is a class in the Magician OpenGL package. I don''t know exactly what it does but the documentation says it is microsecond accurate and I assume they use the clock() call. but it does not seem much more accurate than the system call. If you guys are calculating fps with
long - long / int you will not get decimal fractions, just a thought. Using the alarm thread may be more accurate than 50 ms but you cannot guarantee than it will wake up anywhere near 30 ms. Java only says it will wake up sometime after 30 ms.

I wanrned you! Didn''t I warn you?! That colored chalk was forged by Lucifer himself!

#9 snowmoon   Members   -  Reputation: 122

Like
Likes
Like

Posted 18 November 2000 - 03:33 AM

System.currentTimeMillis() can be much more accurate. Unfortunatly under the windows jdk it's tied to a very innacurate timing method. Under windows there ARE more accurate timing measures. There is a CPU instruction to get the clock cycles, and combine that with the cycles per second variable and you have very low latency nanosecond timing.

I was able to do the timing I wanted by using a forced painting loop. I fond out the even using an overzelous repaint() loop will only get you 2-5 fps max. What you want to do for compnent x if you want to time it's drawing routine...

long frame = 0;
long startTime = System.currentTimeMillis();
Graphics g = x.getGraphics();
while(true) {
x.update(g);
frame++;
if ( frame % 30 == 0 && frmae != 0 ) {
System.out.println((double)1000.00/((System.currentTimeMillis()-startTime)/frames) + " Frames /sec");
} // end if
} // end while

This will give you failry accurate timing.

I'm also going to need millisecond timing to do updates on the positions of everything on the screen, so eventually I will need to have accurate time per frame. I may end up keeping a running average just so I know how many units to update my players by.

On a site note....

Does anyone have examples of MemoryImageSource when used in conjunction with the setAnimated(true) flag? I am having promising results with hand done System.arraycopy image routines but they never display on the screen...... hmmm

Edited by - snowmoon on November 18, 2000 10:45:33 AM

#10 felonius   Members   -  Reputation: 122

Like
Likes
Like

Posted 01 January 2001 - 09:45 PM

I just tried wrapping clock() in JNI and it turns out that that uses the coarse grnaularity of as the JDK millisecond timing function.

Using the processor cycle counter seems to be the best way to go. (if you can accept the code is no longer 100% pure java that is)

Jacob Marner


#11 Jerry Lynn   Members   -  Reputation: 122

Like
Likes
Like

Posted 10 January 2001 - 10:41 AM

The JMF API includes classes that support high-resolution, multimedia timing. I haven''t tried this myself, but you may be able to use those classes for timing your game loop.

The two classes in particular to look at would be TimeBase and Clock.

While this would require installing the JMF API, you would still be pure Java. Check out the JMF site at Javasoft.com for more information:

http://www.javasoft.com/products/java-media/jmf/index.html

#12 felonius   Members   -  Reputation: 122

Like
Likes
Like

Posted 10 January 2001 - 11:06 PM

quote:
Original post by Jerry Lynn

While this would require installing the JMF API, you would still be pure Java.


I would call that stretching the definition of pure Java. A pure Java program should be able to run on any platform, but all the optional packages and especially those that are still in beta can hardly be found on anything but Sun''s own implementation.

Sun is spewing out new APIs so fast that no other implementation can keep up. In my terminology (I would apprecaite a link to a precise definition) a 100% pure Java program uses only those API calls part of the core JDK API (downloaded with the JDK) or any library written entirely in Java using this API.

Jacob Marner



#13 Jerry Lynn   Members   -  Reputation: 122

Like
Likes
Like

Posted 11 January 2001 - 07:56 AM

Actually there is a cross-platform version of the JMF that is pure Java and will work on all platforms that the JDK 1.2 is available for. In addition there are ''performance'' packs available for Windows, Solaris, and for Linux available from Blackdown.

I would probably not recommend using the cross-platform pack for decoding full screen MPEG''s, but I think you would still be able to use the TimeBase class for loop timing.

So in essence JMF is pure Java, but you can achieve superior performance by installing a version specific for the OS you are using (if available).


#14 felonius   Members   -  Reputation: 122

Like
Likes
Like

Posted 11 January 2001 - 01:55 PM

If there exists versions of JMF written in pure Java then those versions only have access to API calls from the standard Java API. This means that something like the Timebase functions also must call something in the standard API. In essense this means that they cannot get a higher time accuracy than calls made yourself to the standard API.

So it simply does not make sense that (cross-platform) JMF can giver higher accuracy. For the platform specific optimizations I believe you but not for the other ones. It might be that the cross platform version of JMF simply uses System.currentTimeMillis() which gives a good granularity on most systems (except Windows) and the optimized version for Windows calls the clock cycle counter via JNI.

Cheers,
Jacob




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS