backport: AtomicLongFieldUpdater support

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

backport: AtomicLongFieldUpdater support

Moran Or Avigdor
Are there any plans to support a backport version of java.util.concurrent.atomic.AtomicLongFieldUpdater ?
e.g. edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLongFieldUpdater

Thank you in advance,
Moran.

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: backport: AtomicLongFieldUpdater support

Doug Lea
Moran Or Avigdor wrote:
> Are there any plans to support a backport version of
> java.util.concurrent.atomic.AtomicLongFieldUpdater ?
> e.g.
> edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLongFieldUpdater
>

While it would logically be possible to do this without
Java 5 native support, it would be so pathetically slow that
Dawid is doing you a big favor by not including them. :-)

-Doug

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: backport: AtomicLongFieldUpdater support

Dawid Kurzyniec
Doug Lea wrote:

> Moran Or Avigdor wrote:
>
>> Are there any plans to support a backport version of
>> java.util.concurrent.atomic.AtomicLongFieldUpdater ?
>> e.g.
>> edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLongFieldUpdater
>>
>>
>
> While it would logically be possible to do this without
> Java 5 native support, it would be so pathetically slow that
> Dawid is doing you a big favor by not including them. :-)
>
Yep. It would have to use reflection combined with synchronization. Even
despite improvements in reflection performance, this does not seem to be
a viable option.

Regards,
Dawid

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: backport: AtomicLongFieldUpdater support

Moran Or Avigdor
Dawid,
Thank you for your feedback.

Isn't the reflection done only once per newUpdater call?
If a LockedUpdater is supplied then the synchronization should work well for its implications.

Although it is not correct to state that on JDK1.4 the underlying JVM doesn't supports lockless CompareAndSet for longs, but the
effect will return the needed Updater.

Am I missing something in my assesment?
Am I correct to assume that the LockedUpdater should suffice?

Thank you in advance.
-Moran


On 11/30/05, Dawid Kurzyniec <[hidden email]> wrote:
Doug Lea wrote:

> Moran Or Avigdor wrote:
>
>> Are there any plans to support a backport version of
>> java.util.concurrent.atomic.AtomicLongFieldUpdater ?
>> e.g.
>> edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLongFieldUpdater
>>
>>
>
> While it would logically be possible to do this without
> Java 5 native support, it would be so pathetically slow that
> Dawid is doing you a big favor by not including them. :-)
>
Yep. It would have to use reflection combined with synchronization. Even
despite improvements in reflection performance, this does not seem to be
a viable option.

Regards,
Dawid



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: backport: AtomicLongFieldUpdater support

Dawid Kurzyniec
Moran Or Avigdor wrote:

> Dawid,
> Thank you for your feedback.
>
> Isn't the reflection done only once per newUpdater call?
> If a LockedUpdater is supplied then the synchronization should work
> well for its implications.
>
> Although it is not correct to state that on JDK1.4 the underlying JVM
> doesn't supports lockless CompareAndSet for longs, but the
> effect will return the needed Updater.
>
> Am I missing something in my assesment?
> Am I correct to assume that the LockedUpdater should suffice?
>
I was thinking of something along the lines of the older JSR 166
emulation code:

http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/emulation/java/util/concurrent/atomic/AtomicLongFieldUpdater.java

but it requires, in the best case, two reflective calls
(Field.getLong/Field.setLong) per an operation. It may be interesting to
test that and see how much overhead that would cause (reflection has a
fast path for unchecked accessor methods), but Doug's comments suggest
that they've tried it and it was not good.

On the other hand, you're suggesting using sun.misc.Unsafe. This may be
quite an interesting idea. The backport already uses sun.misc.Perf for
microsecond-precision timer, if the class can be found, and otherwise
falling back to System.currentTimeMillis(). Maybe similar approach could
be taken for sun.misc.Unsafe?...

On the other hand, why do you need the field updater in the first place?
Chances are, you have a non-blocking algorithm that you want to port to
1.4. It is usually quite easy to modify such algorithms to use
synchronization instead of atomic field updaters. Example of this is
ConcurrentSkipListMap and some other classes in j.u.c. that I've
backported this way.

(Technically, the algorithm is non-blocking no more, but the locks are
held so briefly that it retains very high scalability, for the price of
higher single-thread execution overhead.)

Regards,
Dawid

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: backport: AtomicLongFieldUpdater support

Moran Or Avigdor
Dawid,

The port to JDK1.4 is only required for backwards compatibility of JDK1.5 code.
Since the introduction of java.util.concurrent, we rely on backport-util-concurrent.jar for
the relevant compatibility. needless to say, we had to apply some ruling to adapt it seamlessly.

Regarding the reflection based implementation -
1. It might apply an overhead, and to by pass the reflection only a "LockableLong" interface can assist.
This would then define a getLong and setLong methods to safely invoke.
2. I've noticed that in some usages, a "private static final AtomicLongFieldUpdater" was declared,
which implies that in the LockUpdater the synchronized would lock the Field itself. If this class instances
are numerous, it would deny access to different instances invoking the same operation on the same field!
The "LockableLong" interface can have an indication "isStatic" to lock the object itself or the Field.

Regarding the use of sun.misc.Unsafe -
That was my first intention. But I ran into security access problems and decided to look into later.
But if I understand it correctly, it should provide me with the correct result as in JDK1.5
In cases where it is not defined, falling back on reflection should do the trick.

The backwards compatibility is a must if applications need to move forward and adopt new concurrent
methods. That is the major concern for us when looking into newly introduced classes.

Thank you.
-Moran


On 12/5/05, Dawid Kurzyniec <[hidden email]> wrote:
Moran Or Avigdor wrote:

> Dawid,
> Thank you for your feedback.
>
> Isn't the reflection done only once per newUpdater call?
> If a LockedUpdater is supplied then the synchronization should work
> well for its implications.
>
> Although it is not correct to state that on JDK1.4 the underlying JVM
> doesn't supports lockless CompareAndSet for longs, but the
> effect will return the needed Updater.
>
> Am I missing something in my assesment?
> Am I correct to assume that the LockedUpdater should suffice?
>
I was thinking of something along the lines of the older JSR 166
emulation code:

http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/emulation/java/util/concurrent/atomic/AtomicLongFieldUpdater.java

but it requires, in the best case, two reflective calls
(Field.getLong/Field.setLong) per an operation. It may be interesting to
test that and see how much overhead that would cause (reflection has a
fast path for unchecked accessor methods), but Doug's comments suggest
that they've tried it and it was not good.

On the other hand, you're suggesting using sun.misc.Unsafe. This may be
quite an interesting idea. The backport already uses sun.misc.Perf for
microsecond-precision timer, if the class can be found, and otherwise
falling back to System.currentTimeMillis(). Maybe similar approach could
be taken for sun.misc.Unsafe?...

On the other hand, why do you need the field updater in the first place?
Chances are, you have a non-blocking algorithm that you want to port to
1.4. It is usually quite easy to modify such algorithms to use
synchronization instead of atomic field updaters. Example of this is
ConcurrentSkipListMap and some other classes in j.u.c. that I've
backported this way.

(Technically, the algorithm is non-blocking no more, but the locks are
held so briefly that it retains very high scalability, for the price of
higher single-thread execution overhead.)

Regards,
Dawid



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: backport: AtomicLongFieldUpdater support

Dawid Kurzyniec
Moran Or Avigdor wrote:

>
> Regarding the reflection based implementation -
> 1. It might apply an overhead, and to by pass the reflection only a
> "LockableLong" interface can assist.
> This would then define a getLong and setLong methods to safely invoke.


Or, one could follow the original convention of atomic updaters: a
factory method that returns an appropriate subclass of the updater:
unsafe-based or reflection-based.

> 2. I've noticed that in some usages, a "private static final
> AtomicLongFieldUpdater" was declared,
> which implies that in the LockUpdater the synchronized would lock the
> Field itself. If this class instances
> are numerous, it would deny access to different instances invoking the
> same operation on the same field!
> The "LockableLong" interface can have an indication "isStatic" to lock
> the object itself or the Field.


I agree with you that the "lock per updater" emulation strategy may be
too coarse-grained (I suspect that it was adapted for
AtomicLongFieldUpdater.LockedUpdater anyway because of the assumption
that most Java 5.0 implementations do natively support atomic long CAS).
However, locking on the Field is actually even worse (Fields are also
"static"; they belong to the class, not the instance). Locking on the
target object, on the other hand, may be too coarse-grained, too, only
in a different dimension: a single class may have multiple volatile
fields updatable via independent different updaters, and locking on the
object would make them mutually exclusive. In fact, finding the right
object to synchronize on is a hairy issue if you want both performance
and scalability. The best solution that comes to my mind is to use lock
stripping - e.g. define a global array of objects, and finding the lock
index as an (identity) hash code of the pair (updater,object). Better
ideas welcome.

>
> The backwards compatibility is a must if applications need to move
> forward and adopt new concurrent
> methods. That is the major concern for us when looking into newly
> introduced classes.
>
It was the motivation behind the backport. But my point of view always
has been that, if the overhead introduced by emulation of a certain
feature is prohibitively high, it's better to leave it out, rather than
having the users learn the hard way - e.g. finding out at deployment
time that their application falls apart under load and does not scale
beyond 2 CPUs despite using a "scalable", non-blocking algorithm. With
the atomics, we're talking about a hardware-supported, JIT-inlined,
atomic memory update vs. "synchronized" + two native method calls to a
dynamically linked library + other reflection stuff +
System.identityHashCode().

Bottom line: I am leaning to try to explore several options for
backporting field updaters - both reflection-based and Unsafe-based.
(Contributions and comments welcome). But, I will include this in the
backport only if it can obtain satisfactory performance (say, no more
than 100% overhead over current backported Atomic classes) on most of
the current platforms. I have other things on the queue though, so I
cannot guarantee a timeline earlier than Feb 2006.

BTW. Since the backport, and the JSR 166 are public domain, you are
welcome to do as you please - it's not that hard to take the emulated
updater from early JSR 166 and add it locally to your backport to test
how things are going.

Regards,
Dawid


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: backport: AtomicLongFieldUpdater support

Moran Avigdor
Dawid,
    There were some insights in your responses that I would also like to
pursue.
    In the meanwhile I have taken the liberty to emulate the updater for
my specific needs.

    It would be great if success comes either way and field updaters
will be bakported.
    Thank you very much for your time and patience.

Regards,
Moran


Dawid Kurzyniec wrote:

> Moran Or Avigdor wrote:
>
>>
>> Regarding the reflection based implementation -
>> 1. It might apply an overhead, and to by pass the reflection only a
>> "LockableLong" interface can assist.
>> This would then define a getLong and setLong methods to safely invoke.
>
>
> Or, one could follow the original convention of atomic updaters: a
> factory method that returns an appropriate subclass of the updater:
> unsafe-based or reflection-based.
>
>> 2. I've noticed that in some usages, a "private static final
>> AtomicLongFieldUpdater" was declared,
>> which implies that in the LockUpdater the synchronized would lock the
>> Field itself. If this class instances
>> are numerous, it would deny access to different instances invoking
>> the same operation on the same field!
>> The "LockableLong" interface can have an indication "isStatic" to
>> lock the object itself or the Field.
>
>
> I agree with you that the "lock per updater" emulation strategy may be
> too coarse-grained (I suspect that it was adapted for
> AtomicLongFieldUpdater.LockedUpdater anyway because of the assumption
> that most Java 5.0 implementations do natively support atomic long
> CAS). However, locking on the Field is actually even worse (Fields are
> also "static"; they belong to the class, not the instance). Locking on
> the target object, on the other hand, may be too coarse-grained, too,
> only in a different dimension: a single class may have multiple
> volatile fields updatable via independent different updaters, and
> locking on the object would make them mutually exclusive. In fact,
> finding the right object to synchronize on is a hairy issue if you
> want both performance and scalability. The best solution that comes to
> my mind is to use lock stripping - e.g. define a global array of
> objects, and finding the lock index as an (identity) hash code of the
> pair (updater,object). Better ideas welcome.
>
>>
>> The backwards compatibility is a must if applications need to move
>> forward and adopt new concurrent
>> methods. That is the major concern for us when looking into newly
>> introduced classes.
>>
> It was the motivation behind the backport. But my point of view always
> has been that, if the overhead introduced by emulation of a certain
> feature is prohibitively high, it's better to leave it out, rather
> than having the users learn the hard way - e.g. finding out at
> deployment time that their application falls apart under load and does
> not scale beyond 2 CPUs despite using a "scalable", non-blocking
> algorithm. With the atomics, we're talking about a hardware-supported,
> JIT-inlined, atomic memory update vs. "synchronized" + two native
> method calls to a dynamically linked library + other reflection stuff
> + System.identityHashCode().
>
> Bottom line: I am leaning to try to explore several options for
> backporting field updaters - both reflection-based and Unsafe-based.
> (Contributions and comments welcome). But, I will include this in the
> backport only if it can obtain satisfactory performance (say, no more
> than 100% overhead over current backported Atomic classes) on most of
> the current platforms. I have other things on the queue though, so I
> cannot guarantee a timeline earlier than Feb 2006.
>
> BTW. Since the backport, and the JSR 166 are public domain, you are
> welcome to do as you please - it's not that hard to take the emulated
> updater from early JSR 166 and add it locally to your backport to test
> how things are going.
>
> Regards,
> Dawid
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest