Warming up Hotspot

C

cppaddict

I found the code below in an interesting article about how to measure
execution time with greater accuracy than System.currentTimeMillis()
offers:

http://www.javaworld.com/javaworld/javaqa/2003-01/01-qa-0110-timing.html

My question is about the first "for" loop in the code below, which,
according to the comments, is intended to "warm up" hotspot. Can
someone explain what it's doing there? Why do you need to warm up
hotspot? Does it create performance gains? If so, how and why?

Thanks,
John


public static void main (String [] args)
{
// JIT/hotspot warmup:
for (int r = 0; r < 3000; ++ r) System.currentTimeMillis ();

long time = System.currentTimeMillis (), time_prev = time;

for (int i = 0; i < 5; ++ i)
{
// Busy wait until system time changes:
while (time == time_prev)
time = System.currentTimeMillis ();

System.out.println ("delta = " + (time - time_prev) + "
ms");
time_prev = time;
}
}
 
C

Chris Uppal

cppaddict said:
My question is about the first "for" loop in the code below, which,
according to the comments, is intended to "warm up" hotspot. Can
someone explain what it's doing there? Why do you need to warm up
hotspot? Does it create performance gains? If so, how and why?

There are two parts to the answer.

The first is that "Hotspot" does adaptive optimisation. It looks for the
hotspots in the code (hence the name ;-) where most of the execution time is
being consumed and puts most of its optimisation efforts there. Don't take the
following as technically correct, but as an /indication/ of how it works, you
can imagine that the JVM uses a built-in interpreter for code the first time
it is run, and as it decides that some code is running often enough to be
"worth optimising" it first compiles it, and then (if the code is run still
more) eventually decides to put real effort into optimising it by (say)
inlining method calls, eliminating dead stores, eliminating dead code, inlining
method /dispatch/ (removing "virtual" method calls) and what-not. So the
general idea is that since the optimiser doesn't kick in until after the code
has run for some time, it can be a good idea to run the code for a while to
give the optimiser time to do its stuff before you start measuring it.

BTW, the details of how and when all this is done depends on the JVM
implementation. For instance one of the IBM JVM implementations doesn't use an
interpreter at all -- it uses a very fast, but very simple, compiler on all
bytecode even if it's only ever executed once. Another point in the spectrum
is Sun's "server" JVM (the -server option) which not only applies more
optimisations than the desktop version, but also applies them sooner. The Sun
JVMs also have options which affect how the optimiser works, which can be
useful for reducing the uncertainty in benchmarking.


However, the code in question:
// JIT/hotspot warmup:
for (int r = 0; r < 3000; ++ r) System.currentTimeMillis ();

looks like nonsense to me. There is no point in executing currentTimeMillis()
3000 times. At /best/ all that will happen is that you persuade the optimiser
that the currentTimeMillis() function needs to be optimised heavily !

The rest of the code then waits for the millisecond timer to click over, which
is sensible in itself, but why-oh-why does he limit the number of loops?
Pointless, and probably wrong (even after the println() is removed, as it
obviously has to be for real use).

-- chris
 
C

cppaddict

Chris,

Thanks very much for the explanation.
The rest of the code then waits for the millisecond timer to click over, which
is sensible in itself, but why-oh-why does he limit the number of loops?
Pointless, and probably wrong (even after the println() is removed, as it
obviously has to be for real use).

I don't think there is a "real" use in the case. The purpose of the
code is just to demonstrate that currentTimeMillis() can measure
execution speed only to within 10ms.

Thanks again,
cpp
 
P

Paul Lutus

cppaddict said:
Chris,

Thanks very much for the explanation.


I don't think there is a "real" use in the case. The purpose of the
code is just to demonstrate that currentTimeMillis() can measure
execution speed only to within 10ms.

This is entirely platform-dependent. There is nothing about
currentTimeMillis() that limits the resolution of its result -- that is
entirely up to the platform. It has nothing to do with Java, except insofar
as Java is dependent on native-code/hardware resources to some extent on
all platforms.

IOW you are measuring your operating system's (or your hardware's) time
slice size, not anything about Java.
 
C

Carl Howells

Paul said:
IOW you are measuring your operating system's (or your hardware's) time
slice size, not anything about Java.

Yep. It seems to be OS dependent, from what I've found.

On windows 9x: 40 ms or 50 ms displayed minimum granularity. Odd that
it sometimes changes.

On windows NT/2k/XP: 10 ms

On unix/linux: 1 ms

I think there's a new timing call added somewhere recently that is
supposed to feature better resolution on all platforms, but I haven't
tried using it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top