|
View:
New views
13 Messages
—
Rating Filter:
Alert me
|
|
|
Accurate CPU timing on Windows -- How?
We've done a good amount of JMX instrumentation of our application --
including various embedded timing metrics, both wall clock and CPU
times.
The issue we're seeing is that at least on Windows the CPU thread times produced by ThreadMXBean.getCurrentThreadCpuTime() are horribly inaccurate. We attempt to time various relatively short-lived requests and they all give an elapsed CPU time of 0. I can see that granularity in the timer might lead to some of this, but we have many such requests and they all show an elapsed time of 0 -- whereas one would expect that granularity would lead to sudden large timer jumps during in some measurement intervals.
-- Jess Holle P.S. I have noticed other substantial issues in this area as well, including:
=========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help".PLATFORM_MBEAN_SERVER.getAttribute( OS_MBEAN_NAME, "ProcessCpuTime" )which is not very efficient at all. |
|
|
Re: Accurate CPU timing on Windows -- How?On Wed, 2007-07-18 at 15:51 -0500, Jess Holle wrote:
> * On Windows [at least], System.currentTimeMillis()'s resolution > is not milliseconds but rather about 0.01 seconds. > * We could use System.nanoTime() instead, but it appears > that acquiring this takes a bit more time. Moreover, > for the usages in question millisecond accuracy is > sufficient, but 0.01 seconds is not always. Jess, this is a kernel issue (kernel precision is typically 10/15 ms), it's not related with java. Michele =========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help". |
|
|
Re: Accurate CPU timing on Windows -- How?
Michele Mazzucco wrote:
So are you saying that System.nanoTime() is:On Wed, 2007-07-18 at 15:51 -0500, Jess Holle wrote:
While all this is annoying the bigger issue is thread CPU time... -- Jess Holle =========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help". |
|
|
Re: Accurate CPU timing on Windows -- How?Jess,
I'm saying (a), but it's not a windows only problem. It applies to linux as well (I think it applies to all non-realtime os). Michele On Thu, 2007-07-19 at 06:35 -0500, Jess Holle wrote: > Michele Mazzucco wrote: > > On Wed, 2007-07-18 at 15:51 -0500, Jess Holle wrote: > > > > > * On Windows [at least], System.currentTimeMillis()'s resolution > > > is not milliseconds but rather about 0.01 seconds. > > > * We could use System.nanoTime() instead, but it appears > > > that acquiring this takes a bit more time. Moreover, > > > for the usages in question millisecond accuracy is > > > sufficient, but 0.01 seconds is not always. > > > > > Jess, > > > > this is a kernel issue (kernel precision is typically 10/15 ms), it's > > not related with java. > > > So are you saying that System.nanoTime() is: > a. No more accurate than System.currentTimeMillis() on Windows > *or* > b. Is sufficiently costly that Sun doesn't want to implement > System.currentTimeMillis() via System.nanoTime()'s internals? > Clearly (b) is possible in that one can compute an offset by examining > System.currentTimeMillis() and System.nanoTime() on startup, doing all > timing via nanoTime() and then using the startup numbers to convert > from nanoTime() results to currentTimeMillis() results. I do it in a > few places to avoid having to obtain both types of times when I > already have nanoTime() for some reason. I have to assume that (b) is > more costly, though -- from my own results. > > While all this is annoying the bigger issue is thread CPU time... > > -- > Jess Holle > =========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help". |
|
|
Re: Accurate CPU timing on Windows -- How?
Michele Mazzucco wrote:
Actually a little experimentation shows (a) is *not* the case.Jess, I'm saying (a), but it's not a windows only problem. It applies to linux as well (I think it applies to all non-realtime os). Try: public class TestWhen running this, I get: 0.002209499That is clearly *far* more accurate than using System.currentTimeMillis() [and switching the conversion factor], where I get: 0.0[The average of these does actually give exactly 0.003 seconds, which is correct.] This shows that either the issue is (b) or Sun's System.currentTimeMillis() is unnecessarily inaccurate (though this may well impact more than just Windows). -- Jess Holle On Thu, 2007-07-19 at 06:35 -0500, Jess Holle wrote: =========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help". |
|
|
Re: Accurate CPU timing on Windows -- How?Without knowing much in this regard, I seem to recall that
System.currentTimeMillis varies down to roughly 50 milliseconds. If this is the case, using currentTimeMillis for timings of chunks smaller than 50 milliseconds is not very accurate. Regards, Eske Jess Holle skrev: > Michele Mazzucco wrote: >> Jess, >> >> I'm saying (a), but it's not a windows only problem. It applies to linux >> as well (I think it applies to all non-realtime os). >> > Actually a little experimentation shows (a) is *not* the case. > > Try: > > public class Test > { > public static void main( String args[] ) > throws Exception > { > for ( int ii = 0; ii < 20; ++ii ) > { > final long start = System.nanoTime(); > Thread.sleep( 3L ); > final long end = System.nanoTime(); > System.out.println( (double) ( end - start ) / 1.0e9 ); > } > } > } > > When running this, I get: > > 0.002209499 > 0.003041727 > 0.002880813 > 0.002905955 > 0.003513295 > 0.002158934 > 0.00289562 > 0.002910706 > 0.002923277 > 0.002881372 > 0.002910984 > 0.002908471 > 0.002911264 > 0.002274591 > 0.003108216 > 0.002893664 > 0.002867683 > 0.002905676 > 0.002910984 > 0.002916013 > > That is clearly *far* more accurate than using > System.currentTimeMillis() [and switching the conversion factor], where > I get: > > 0.0 > 0.0 > 0.01 > 0.0 > 0.0 > 0.01 > 0.0 > 0.0 > 0.01 > 0.0 > 0.0 > 0.01 > 0.0 > 0.0 > 0.0 > 0.01 > 0.0 > 0.0 > 0.01 > 0.0 > > [The average of these does actually give exactly 0.003 seconds, which is > correct.] > > This shows that either the issue is (b) or Sun's > System.currentTimeMillis() is unnecessarily inaccurate (though this may > well impact more than just Windows). > > -- > Jess Holle >> On Thu, 2007-07-19 at 06:35 -0500, Jess Holle wrote: >> >>> Michele Mazzucco wrote: >>> >>>> On Wed, 2007-07-18 at 15:51 -0500, Jess Holle wrote: >>>> >>>>> * On Windows [at least], System.currentTimeMillis()'s resolution >>>>> is not milliseconds but rather about 0.01 seconds. >>>>> * We could use System.nanoTime() instead, but it appears >>>>> that acquiring this takes a bit more time. Moreover, >>>>> for the usages in question millisecond accuracy is >>>>> sufficient, but 0.01 seconds is not always. >>>>> >>>> Jess, >>>> >>>> this is a kernel issue (kernel precision is typically 10/15 ms), it's >>>> not related with java. >>>> >>> So are you saying that System.nanoTime() is: >>> a. No more accurate than System.currentTimeMillis() on Windows >>> *or* >>> b. Is sufficiently costly that Sun doesn't want to implement >>> System.currentTimeMillis() via System.nanoTime()'s internals? >>> Clearly (b) is possible in that one can compute an offset by examining >>> System.currentTimeMillis() and System.nanoTime() on startup, doing all >>> timing via nanoTime() and then using the startup numbers to convert >>> from nanoTime() results to currentTimeMillis() results. I do it in a >>> few places to avoid having to obtain both types of times when I >>> already have nanoTime() for some reason. I have to assume that (b) is >>> more costly, though -- from my own results. >>> >>> While all this is annoying the bigger issue is thread CPU time... >>> >>> -- >>> Jess Holle > > > =========================================================================== > For information on the Java Management extensions (JMX), please visit > our home page at http://java.sun.com/products/JavaManagement/ > The JMX-FORUM archives are accessible at http://archives.java.sun.com > To unsubscribe, send email to listserv@... and include in the body > of the message "signoff JMX-FORUM". For general help, send email to > listserv@... and include in the body of the message "help". > =========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help". |
|
|
Re: Accurate CPU timing on Windows -- How?Jess,
you didn't get my point. What I'm saying is that the values you get are not accurate. >From the javadoc you can see: public static long currentTimeMillis() Returns the current time in milliseconds. *Note that while the unit of time of the return value is a millisecond, the granularity of the value depends on the underlying operating system and may be larger*. For example, many operating systems measure time in units of tens of milliseconds. Returns the current value of the most precise available system timer, in nanoseconds. This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative). This method provides nanosecond precision, *but not necessarily nanosecond accuracy*. No guarantees are made about how frequently values change. Differences in successive calls that span greater than approximately 292 years (2^63 nanoseconds) will not accurately compute elapsed time due to numerical overflow. Michele On Thu, 2007-07-19 at 07:12 -0500, Jess Holle wrote: > Michele Mazzucco wrote: > > Jess, > > > > I'm saying (a), but it's not a windows only problem. It applies to linux > > as well (I think it applies to all non-realtime os). > > > Actually a little experimentation shows (a) is *not* the case. > > Try: > public class Test > { > public static void main( String args[] ) > throws Exception > { > for ( int ii = 0; ii < 20; ++ii ) > { > final long start = System.nanoTime(); > Thread.sleep( 3L ); > final long end = System.nanoTime(); > System.out.println( (double) ( end - start ) / 1.0e9 ); > } > } > } > When running this, I get: > 0.002209499 > 0.003041727 > 0.002880813 > 0.002905955 > 0.003513295 > 0.002158934 > 0.00289562 > 0.002910706 > 0.002923277 > 0.002881372 > 0.002910984 > 0.002908471 > 0.002911264 > 0.002274591 > 0.003108216 > 0.002893664 > 0.002867683 > 0.002905676 > 0.002910984 > 0.002916013 > That is clearly *far* more accurate than using > System.currentTimeMillis() [and switching the conversion factor], > where I get: > 0.0 > 0.0 > 0.01 > 0.0 > 0.0 > 0.01 > 0.0 > 0.0 > 0.01 > 0.0 > 0.0 > 0.01 > 0.0 > 0.0 > 0.0 > 0.01 > 0.0 > 0.0 > 0.01 > 0.0 > [The average of these does actually give exactly 0.003 seconds, which > is correct.] > > This shows that either the issue is (b) or Sun's > System.currentTimeMillis() is unnecessarily inaccurate (though this > may well impact more than just Windows). > > -- > Jess Holle > > On Thu, 2007-07-19 at 06:35 -0500, Jess Holle wrote: > > > > > Michele Mazzucco wrote: > > > > > > > On Wed, 2007-07-18 at 15:51 -0500, Jess Holle wrote: > > > > > > > > > * On Windows [at least], System.currentTimeMillis()'s resolution > > > > > is not milliseconds but rather about 0.01 seconds. > > > > > * We could use System.nanoTime() instead, but it appears > > > > > that acquiring this takes a bit more time. Moreover, > > > > > for the usages in question millisecond accuracy is > > > > > sufficient, but 0.01 seconds is not always. > > > > > > > > > Jess, > > > > > > > > this is a kernel issue (kernel precision is typically 10/15 ms), it's > > > > not related with java. > > > > > > > So are you saying that System.nanoTime() is: > > > a. No more accurate than System.currentTimeMillis() on Windows > > > *or* > > > b. Is sufficiently costly that Sun doesn't want to implement > > > System.currentTimeMillis() via System.nanoTime()'s internals? > > > Clearly (b) is possible in that one can compute an offset by examining > > > System.currentTimeMillis() and System.nanoTime() on startup, doing all > > > timing via nanoTime() and then using the startup numbers to convert > > > from nanoTime() results to currentTimeMillis() results. I do it in a > > > few places to avoid having to obtain both types of times when I > > > already have nanoTime() for some reason. I have to assume that (b) is > > > more costly, though -- from my own results. > > > > > > While all this is annoying the bigger issue is thread CPU time... > > > > > > -- > > > Jess Holle > =========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help". |
|
|
Re: Accurate CPU timing on Windows -- How?Michele Mazzucco wrote:
> Jess, > > you didn't get my point. What I'm saying is that the values you get are > not accurate. > > > >From the javadoc you can see: > public static long currentTimeMillis() > Returns the current time in milliseconds. *Note that while the > unit of time of the return value is a millisecond, the > granularity of the value depends on the underlying operating > system and may be larger*. For example, many operating systems > measure time in units of tens of milliseconds. > > Returns the current value of the most precise available system timer, in > nanoseconds. > > This method can only be used to measure elapsed time and is not related > to any other notion of system or wall-clock time. The value returned > represents nanoseconds since some fixed but arbitrary time (perhaps in > the future, so values may be negative). This method provides nanosecond > precision, *but not necessarily nanosecond accuracy*. No guarantees are > made about how frequently values change. Differences in successive calls > that span greater than approximately 292 years (2^63 nanoseconds) will > not accurately compute elapsed time due to numerical overflow. > wall clock time via some simple math on startup. Thus the only reason not to rework System.currentTimeMillis() to do so and guarantee millisecond accuracy [barring a nanoTime() timer that is not even that accurate] is if nanoTime() [plus the conversion necessary to relate to wall clock time] is too expensive. Otherwise System.currentTimeMillis() should go the way of the dinosaur. Unfortunately I had done some testing and found System.nanoTime() to be significantly more expensive than System.currentTimeMillis() -- which leads to a tradeoff between great numbers and great speed. To date I'm going with speed, which I guess means it all comes down to a choice between really inaccurate results and paying a bit more for nanoTime() results. -- Jess Holle =========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help". |
|
|
Re: Accurate CPU timing on Windows -- How?Which all is off the main thrust of my original e-mail:
Is there any way to get more accurate thread CPU times? ThreadMXBean is extraordinarily inaccurate in this regard! -- Jess Holle Jess Holle wrote: > Michele Mazzucco wrote: >> Jess, >> >> you didn't get my point. What I'm saying is that the values you get are >> not accurate. >> >> >> >From the javadoc you can see: >> public static long currentTimeMillis() >> Returns the current time in milliseconds. *Note that while the >> unit of time of the return value is a millisecond, the >> granularity of the value depends on the underlying operating >> system and may be larger*. For example, many operating systems >> measure time in units of tens of milliseconds. >> >> Returns the current value of the most precise available system timer, in >> nanoseconds. >> >> This method can only be used to measure elapsed time and is not related >> to any other notion of system or wall-clock time. The value returned >> represents nanoseconds since some fixed but arbitrary time (perhaps in >> the future, so values may be negative). This method provides nanosecond >> precision, *but not necessarily nanosecond accuracy*. No guarantees are >> made about how frequently values change. Differences in successive calls >> that span greater than approximately 292 years (2^63 nanoseconds) will >> not accurately compute elapsed time due to numerical overflow. >> > Yes, but as per my previous point you can relate nanoTime() results to > wall clock time via some simple math on startup. Thus the only reason > not to rework System.currentTimeMillis() to do so and guarantee > millisecond accuracy [barring a nanoTime() timer that is not even that > accurate] is if nanoTime() [plus the conversion necessary to relate to > wall clock time] is too expensive. Otherwise > System.currentTimeMillis() should go the way of the dinosaur. > > Unfortunately I had done some testing and found System.nanoTime() to > be significantly more expensive than System.currentTimeMillis() -- > which leads to a tradeoff between great numbers and great speed. To > date I'm going with speed, which I guess means it all comes down to a > choice between really inaccurate results and paying a bit more for > nanoTime() results. > > -- > Jess Holle =========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help". |
|
|
|
|
|
Re: Accurate CPU timing on Windows -- How?Eamonn McManus wrote:
> Jess, > > I don't know the answer to your question about > ThreadMXBean.getCurrentThreadCpuTime(), but I've forwarded it to some people > who might. > > Regarding your observation >> There is no more efficient way to get at the Sun-specific OS MBean >> attribute, "ProcessCpuTime", than >> PLATFORM_MBEAN_SERVER.getAttribute( OS_MBEAN_NAME, "ProcessCpuTime" ) >> which is not very efficient at all. >> >> It would be nice if the implementation class was public so one could look up >> the method via reflection at static init time and then directly invoke the >> method object. >> > Point taken. But if you have permission to call method.setAccessible(true) > then you can access the method by reflection today. > me. Instead I just decided to avoid collecting this data by default -- and expose a attribute on my MBeans as to whether they collect this statistic. > Concerning the question of currentTimeMillis() vs nanoTime(), apart from the > precision the methods also differ in their semantics. In particular, if the > system time is adjusted (by the administrator or by NTP, for example), > currentTimeMillis() will reflect the change. But nanoTime() is independent > of the system time, so it is more appropriate for timings. > Ah... Yes, that is worth noting. I should have had more such discussions some time back apparently as I am using currentTimeMillis() since it seemed accurate enough at the time and nanoTime() took a bit longer to collect.. -- Jess Holle =========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help". |
|
|
|
|
|
Re: Accurate CPU timing on Windows -- How?Eamonn McManus wrote:
> Luis-Miguel Alventosa reminded me that though the implementation class is > not public, the com.sun.management.OperatingSystemMXBean interface that it > implements is. So you can just cast the result of > ManagementFactory.getOperatingSystemMXBean() to that interface and access > its getProcessCpuTime() method, or do the same thing via reflection. > Thanks for the pointer! -- Jess Holle =========================================================================== For information on the Java Management extensions (JMX), please visit our home page at http://java.sun.com/products/JavaManagement/ The JMX-FORUM archives are accessible at http://archives.java.sun.com To unsubscribe, send email to listserv@... and include in the body of the message "signoff JMX-FORUM". For general help, send email to listserv@... and include in the body of the message "help". |
| Free embeddable forum powered by Nabble | Forum Help |