Atomic double arrays

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

Atomic double arrays

Jonathan Baxter
Is there a reason util.concurrent has no AtomicDoubleArray class?

There is this throw-away line at the end of the package docs: "You can also
hold floats using Float.floatToIntBits and Float.intBitstoFloat conversions,
and doubles using Double.doubleToLongBits and Double.longBitsToDouble
conversions."

But that doesn't seem to help if you want to use the atomic add methods, eg
AtomicLongArray.getAndAdd(int i, long delta), because for doubles a and b, it
is generally not true that Double.doubleToLongBits(a) +
Double.doubleToLongBits(b) = Double.doubleToLongBits(a + b).

Is there another way to do atomic double array ops that doesn't involve using
synchronize?

Thanks,

Jonathan
 
--
Jonathan Baxter
Panscient Technologies
http://www.panscient.com

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

RE: Atomic double arrays

David Holmes
Jonathon,

> Is there a reason util.concurrent has no AtomicDoubleArray class?

Yes because there are no generally available atomic instructions for
operating on floating-point values. So basically your only option is
synchronization using locks.

> There is this throw-away line at the end of the package docs:
> "You can also hold floats using Float.floatToIntBits and
> Float.intBitstoFloat conversions, and doubles using
> Double.doubleToLongBits and Double.longBitsToDouble conversions."
>
> But that doesn't seem to help if you want to use the atomic add
> methods

Right, these techniques allow you to hold float bits and do atomic get/set
and CAS but not general arithmetic - because again there are no atomic
instructions for doing that.

> Is there another way to do atomic double array ops that doesn't
> involve using synchronize?

Nope - locking is really your only option.

Cheers,
David Holmes

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

Re: Atomic double arrays

Doug Lea

>>There is this throw-away line at the end of the package docs:
>>"You can also hold floats using Float.floatToIntBits and
>>Float.intBitstoFloat conversions, and doubles using
>>Double.doubleToLongBits and Double.longBitsToDouble conversions."
>>
>>But that doesn't seem to help if you want to use the atomic add
>>methods
>>    
>>
>
>Right, these techniques allow you to hold float bits and do atomic get/set
>and CAS but not general arithmetic - because again there are no atomic
>instructions for doing that.
>
>  
>
Although, if you absolutely cannot use a lock, you might (but probably
shouldn't)
use something like:

void addToAsDouble(AtomicLong a, double x) {
  for(;;) {
    long b = a.get();
    long u = Double.doubleBitsToLong(x + Double.longBitsToDouble(b));
    if (a.compareAndSet(b, u)) break;
  }
}

This can fail to work in the desired way if you ever hit values that are
== as doubles but have
different bit patterns as longs (like positive and negative zero).  
Conversely if the
value is ever NaN, the bits will be equal, but a double == comparison
would return false,
which would make you expect that CAS would fail.
If you can live with these problems, you mught consider it. Although
the conversion functions are not always cheap, and so this is  not likely
to be faster than locking. But  it might be applicable if you must use
CAS to
avoid deadlock scenarios. (In  which case, you might also need to put in
backoffs
to avoid livelock as well.)

In other words, the short answer is as David said: Use a lock.

-Doug

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest