[concurrency-interest] Non-volatile reads

Aleksey Shipilev shade at redhat.com
Wed Apr 26 11:50:19 EDT 2017


On 04/26/2017 05:11 PM, Bobrowski, Maciej wrote:
> class Foo {
>   int x = 0;
>   volatile int y = 0;
> 
>   void write(int newVal) {
>      x = newVal;
>      y = newVal;
>   }
> 
>   int getX(){ return x; }
> 
> }
> 
> I would like to assume that the compiler is NOT going to rewrite the getX() to a
> constant, and it will actually read it from memory/cache and not from a
> register. Let’s assume one thread is periodically calling write with increasing
> value, and one other thread is reading x.

This is actually a very strong assumption, and it would be violated first in
real life cases.


> Q1. Volatile forces ordering and visibility of writes (x and y) across
> processors. As far as I see it, when volatile write happens, all store buffers
> of that core will be flushed in an exclusive manner (by obtaining exclusive flag
> on the processor). The push will invalidate all other cores cache lines that are
> related to the data written (not sure how though..). Is that correct?

Correct for some hypothesis about how Java accesses are compiled down, and how
the hardware works. For example, "volatile store" does not always mean "flusing
the store buffer". The thing about "exclusive" is really up to cache coherency
mechanism given hardware employs. Etc.


> Q2. Given the above, after the flushing of the buffers happen, the other thread
> will be forced to re-read x from main mem (or L3 cache) and update its local
> value,, effectively seeing the new value. Correct?

Correct for some hypothesis how hardware works.

Generic hardware is not obliged to flush the store buffer completely, or in
order. So one can think up the hypothetical hardware example that only flushes
"y", although it would be hard to implement release-acquire there...

Also, if "x" and "y" are on different cache lines, anything that happens to
cache line holding "y" might not happen (or happen late, or even worse) to cache
line holding "x". Reasoning gets simpler if "y" drags the neighbors in its cache
line.

<insert more fantasies here>


> Q3. Even if y was not volatile, on x-86 the store buffers would eventually be
> flushed, so eventually reading process would see an updated value of x, perhaps
> not latest but non-zero value?

Correct, in the belief that everything else was fine.

<insert more fantasies here>


> Thanks for any pointers/comments.

Now, see, "correct, but..." does not mean "always correct".

Read this:
 http://gee.cs.oswego.edu/dl/html/j9mm.html

What you want is JDK 9 VarHandles "opaque" mode that guarantees progress. Read
carefully, and you will spot exactly the case you are asking about.

In current implementation, "opaque" will indeed issue the compiler barriers
only, letting the hardware cache coherency to figure out the rest. But if we
meet the hardware which does not provide this, it will be fixed in the JDK
itself, not in some obscure code in user codebase.

Thanks,
-Aleksey


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20170426/9392e5a3/attachment.sig>


More information about the Concurrency-interest mailing list