Monday, May 09, 2011

Spin vs. Sleep vs. Join

As I was reading about why Esper sometimes implements Spin Locks instead of thread suspension, I wondered what the actual benefits were. I put together a quick and very simple test to measure elapsed time and CPU utilization of 3 different suspension operations:  (Using java version "1.6.0_21" on Windows 7)
  1. Spin: Capture until (the current time plus the suspend time in ms.) and loop until the current time is equal to or greater than until.
  2. Sleep: Call Thread.sleep()
  3. Join: Call Thread.currentThread().join(). 
This was a single thread, called in main, sleeping for 5 ms. in a loop of  100,000. As it turns out, Spin is the absolute most precise of the three, running with zero loss of precision, but at a cost of 499,905 ms. of CPU time.

Sleep lost the most precision with 1,358 ms. worth of latency and a cost of 31 ms. of CPU time.

Join seems to be the best compromise with zero CPU utilization and only 7 ms. loss of precision.

So the moral of the story, it seems to me, is to always use Join unless you need a hyper-precise wake-up time. Furthermore,  it would seem that Sleep is the worst way to achieve a suspension with much lower precision than Join at an infinitely higher CPU cost.

Output:

SpinLock vs. Sleep vs. Join
Warming Up....
Warm Up Complete
Starting Spin Test
Spin:   500000/499905204500
Starting Sleep Test
Sleep:  501358/31200200
Starting Join Test
Join:   500007/0

====  Update ====

Tested the exact same code using java version "1.6.0_24" on Ubuntu 10.10 X64 and the results were a little different. The Spin did have some precision loss (but not much). The biggest difference was that Join went from zero CPU cost to 3,970 ms cost, making it more expensive than Sleep and with slightly less precision. Not sure what to make of that, except that I need to rerun the tests to make sure there is no skew from background processes or something.

SpinLock vs. Sleep vs. Join
Warming Up....
Warm Up Complete
Starting Spin Test
Spin:   500034/499590000000
Starting Sleep Test
Sleep:  516430/3680000000
Starting Join Test
Join:   516650/3970000000

No comments: