Found a thread from 2006 stating some of the (what seem to be many)
issues with nanoTime():
http://www.velocityreviews.com/forums/t151271-p-systemnanotime-and-multiple-cpuscores.html
like supposedly:
- System.nanoTime() uses QueryPerformanceCounters() on Windows and that
this function is known to have problems on Athlon64 multicore systems
Also here:
which states:
“During my investigations I also found out
that on Windows platforms some chipsets cause leaps forward in time (up
to a
few seconds) when using the QueryPerformanceCounter-Call (which is -to
my
knowledge- the only way to measure in nanoseconds on Windows). This
behavior is
documented under:”
Microsoft Support;
and that says:
“Programs should watch for an unexpected jump by comparing the change in
time as determined by successive calls to QueryPerformanceCounter with
the change in time as determined by successive calls to the GetTickCount
function. If there is a significant jump that is based on
QueryPerformanceCounter(), but no similar increase that is based on
GetTickCount, then it can be assumed that the performance counter just
jumped forward. The code sample at the end of this article demonstrates
how to do this. This operating system’s behavior is by design. The
performance counter adjustment is necessary when the operating system
obtains unreliable data from the chipset.”
I just downloaded the latest Java 1.6 source
(openjdk-6-src-b16-24_apr_2009) and there are three occurrences of
QueryPerformanceCounters() in hotspot/src/os/windows/vm/os_windows.cpp
and one in jdk/src/windows/bin/java_md.c.
You got to love the comment “the best we can do”, which appears to
describe the issue Microsoft described above:
hotspot/src/os/windows/vm/os_windows.cpp-#define NANOS_PER_SEC
CONST64(1000000000)
hotspot/src/os/windows/vm/os_windows.cpp-#define NANOS_PER_MILLISEC
1000000
hotspot/src/os/windows/vm/os_windows.cpp-jlong os::javaTimeNanos() {
hotspot/src/os/windows/vm/os_windows.cpp- if (!has_performance_count) {
hotspot/src/os/windows/vm/os_windows.cpp- return javaTimeMillis() *
NANOS_PER_MILLISEC; // the best we can do.
hotspot/src/os/windows/vm/os_windows.cpp- } else {
hotspot/src/os/windows/vm/os_windows.cpp- LARGE_INTEGER
current_count;
hotspot/src/os/windows/vm/os_windows.cpp:
QueryPerformanceCounter(¤t_count);
hotspot/src/os/windows/vm/os_windows.cpp- double current =
as_long(current_count);
hotspot/src/os/windows/vm/os_windows.cpp- double freq =
performance_frequency;
hotspot/src/os/windows/vm/os_windows.cpp- jlong time =
(jlong)((current/freq) * NANOS_PER_SEC);
hotspot/src/os/windows/vm/os_windows.cpp- return time;
hotspot/src/os/windows/vm/os_windows.cpp- }
hotspot/src/os/windows/vm/os_windows.cpp-}
In addition, here is the javadoc comment in the latest 1.6 source
(openjdk-6-src-b16-24_apr_2009) (I could have gotten from API docs
somewhere, but I was in there anyway) which notes an issue with
nanoTime() with spans of time greater than 292 years (2^63 nanoseconds):
/**
* Returns the current value of the most precise available system
* timer, in nanoseconds.
*
* <p>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<sup>63</sup>
* nanoseconds) will not accurately compute elapsed time due to
* numerical overflow.
*
* <p> For example, to measure how long some code takes to execute:
* <pre>
* long startTime = System.nanoTime();
* // ... the code being measured ...
* long estimatedTime = System.nanoTime() - startTime;
* </pre>
*
* @return The current value of the system timer, in nanoseconds.
* @since 1.5
*/
public static native long nanoTime();
Hope that helps!
Gary
Chuck R. wrote:
+++ RubyTime.java.new 2009-06-01 10:28:42.000000000 -0500
This is actually setting it to whatever nanTime happens to be at any
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email