Re: sun.misc.Unsafe.getAndAddInt implementation, question.

2017-10-14 Thread Gil Tene
A simple answer would be that the field is treated by the method as a 
volatile, and the code is simply staying consistent with that notion. Is an 
optimization possible here? Possibly and Probably. But does it matter? 
No. The source code involved is not performance critical, and is not worth 
optimizing. The interpreter may be running this logic, but no hot path 
would be executing the actual logic in this code... 

Why?  Because the java code you see there is NOT what the hot code would be 
doing on (most) JVMs. Specifically, optimizing JITs can and will identify 
and intrinsify the method, replacing it's body with code that does whatever 
they want it to do. They don't have to perform any of the actual the logic 
in the method, as long as they make sure the method's performs it's 
intended (contracted) function. and that contracted functionality it to 
perform a getAndAddInt on a field, treating it logically as a volatile.

For example, on x86 there is support for atomic add via the XADD 
instruction. Using XADD for this method's functionality has multiple 
advantages over doing the as-coded CAS loop. And most optimizing JITs will 
[transparently] use an XADD in place of a CAS in this case and get rid of 
the loop altogether.

On Saturday, October 14, 2017 at 6:58:17 AM UTC-7, John Hening wrote:
>
> Hello
>
>
> it is an implementation from sun.misc.Unsafe.
>
>
>
> public final int getAndAddInt(Object ptr, long offset, int value) {
>  int curr;
>  do {
> curr = this.getIntVolatile(ptr, offset); (1)
>  } while(!this.compareAndSwapInt(ptr, offset, curr, curr + value)); (2)
>
>  return curr;}
>
>
>
>
>
> Why there is 
> Unsafe.getIntVolatile()
>
>  called instead of 
> Unsafe.getInt()
>
>  here?
>
>
> I am basically familiar with memory models, memory barriers etc., but, 
> perhaps I don't see any something important. 
>
>
> *getIntVolatile* means here: ensure the order of execution: (1) -> (2)
>
>
> It looks something like:
>
>
> curr = read(); 
> acquire();
> CAS operation
>
>
>
> Obviously, acquire() depends on CPU, for example on x86 it is empty, on ARM 
> it is a memory barrier, etc. 
>
>
> My question/misunderstanding:
>
>
> For my eye the order is ensured by data dependency between read of *(ptr + 
> offset)* and *CAS* operation on it. So, I don't see a reason to worry about 
> memory (re)ordering. 
>
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


sun.misc.Unsafe.getAndAddInt implementation, question.

2017-10-14 Thread John Hening


Hello


it is an implementation from sun.misc.Unsafe.



public final int getAndAddInt(Object ptr, long offset, int value) {
 int curr;
 do {
curr = this.getIntVolatile(ptr, offset); (1)
 } while(!this.compareAndSwapInt(ptr, offset, curr, curr + value)); (2)

 return curr;}





Why there is 
Unsafe.getIntVolatile()

 called instead of 
Unsafe.getInt()

 here?


I am basically familiar with memory models, memory barriers etc., but, perhaps 
I don't see any something important. 


*getIntVolatile* means here: ensure the order of execution: (1) -> (2)


It looks something like:


curr = read(); 
acquire();
CAS operation



Obviously, acquire() depends on CPU, for example on x86 it is empty, on ARM it 
is a memory barrier, etc. 


My question/misunderstanding:


For my eye the order is ensured by data dependency between read of *(ptr + 
offset)* and *CAS* operation on it. So, I don't see a reason to worry about 
memory (re)ordering. 



-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.