[concurrency-interest] JSR-133 Cookbook and exit monitor

David Holmes davidcholmes at aapt.net.au
Thu Oct 9 07:15:52 EDT 2014


HI Florian,

Biased-locking and lock coarsening are orthogonal issues. The JIT will
impose lock coarsening when compiling the code. Biased-locking is applied
when actually acquiring a lock.

David
  -----Original Message-----
  From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Florian
Binder
  Sent: Thursday, 9 October 2014 9:01 PM
  To: concurrency-interest at cs.oswego.edu
  Subject: Re: [concurrency-interest] JSR-133 Cookbook and exit monitor


  I would like to throw another question into this interesting discussion:

  How is the relationship between lock coarsening and biased locking?

  Both depends on contention. So if the lock is not contended biased locking
can be used and coarsening is not necessary anymore. But is coarsening
really useful in the case where it is contended so biased locking can not be
used?

  Or is it maybe dependent on the degree of contention like this:

  no contention: biased locking
  low contention: coarsening
  high contention: nothing

  Flo


  Am 09.10.2014 um 06:43 schrieb Nathan Reynolds:

    Generally, I am against lock coarsening.  When facing a problematic
lock, the first thing I do is move everything out of the lock that can
possibly be done.

    In HotSpot version 7349, JIT will generate code with aggressive lock
coarsening.  If the lock becomes contended, then it will iteratively reduce
or remove the coarsening and see if that improves lock throughput.  It will
even go further and automatically pull out all of the code which doesn't
need to be inside the lock.  ;)

    Example #1

    Consider this code which models an actual problem seen.  key.hashCode()
takes a lot of CPU time but fortunately the result is cached inside the key
object.  The problem is that key.hashCode() was being computed inside the
lock for most key objects.

    synchronized (map)
    {
       map.put(key, value);
    }

    The solution was to simply call key.hashCode() just before the lock.
Fortunately, HotSpot doesn't pull this back inside the lock.

    key.hashCode();

    synchronized (map)
    {
       map.put(key, value);
    }

    However, there are some cases where lock coarsening makes sense.

    Example #2

    Consider this code which models an actual problem seen.  In the actual
problem, we weren't dealing with a Map however this code suffices to make
the point.  Each iteration is going to acquire and release the lock.  The
code executed outside of the lock (i.e. the for statement) is very light.
It makes sense to coarsen the lock to surround the entire for loop so that
the lock is acquired and released one time.

    private Map<String, String> map = Collections.synchronizedMap(new
HashMap<>());

    ...
       for (i = 0; i < array.length; i++)
          map.put(array[i], ""));

    Example #3

    Consider this code.  If functionA() is inlined into functionB(), then
there will be 2 synchronized blocks on the same lock back to back to each
other.  The programmer isn't being dumb.  This is where software design
creates a situation where lock coarsening is good.

    void functionA()
    {
       // some code

        synchronized (lock)
        {
            // some more code
        }
    }

    void functionB()
    {
        functionA();

        synchronized (lock)
        {
            // some more code
        }

       // some code
    }

-NathanOn 10/8/2014 8:16 PM, David Holmes wrote:

Thurston writes:
David Holmes-6 wrote
Not only is it allowed, it can easily be performed by the JIT. If that
seems
"unhealthy" you will be really freaked out by lock-coarsening which can
coalesce:

synchronized(x) {
 // aaa
}
// other code
synchronized(x) {
 // bbb
}

into

synchronized(x) {
  // aaa
  // other code
  // bbb
}

where anything in the sync block can of course be further reordered.

Of course this can't be done arbitrarily but it can be done.

Cheers,
David Holmes

Thanks.
To be precise, there is a hb(aaa, bbb), surely that needs to be
respected in the rewritten *coalesced* code; as far as "other code",
anything goes I guess
I don't believe hb has any impact here - as long as intra thread semantics
are obeyed.

Lock coarsening has been employed in hotspot for years now:

http://www.oracle.com/technetwork/java/6-performance-137236.html#2.1.2

Personally I opposed it on liveness grounds - I presume that if you wrote
two close but seperate sync blocks then you had a good reason to do so, most
likely relating to liveness.

David
-----





--
View this message in context:
http://jsr166-concurrency.10961.n7.nabble.com/JSR-133-Cookbook-and-exit-moni
tor-tp11323p11328.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest at cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
Concurrency-interest at cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest






_______________________________________________
Concurrency-interest mailing list
Concurrency-interest at cs.oswego.edu
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20141009/26ef10ec/attachment-0001.html>


More information about the Concurrency-interest mailing list