On Monday, 13 February 2017 at 01:30:57 UTC, ag0aep6g wrote:
This doesn't make sense to me. b depends on a. If I run thread
1 alone, I can expect b to be 1, no? Thread 2 can then a) read
0, write 1; or b) read 1, write 2. How can b be 0 when the
writeln is executed?
An example like this makes more sense to me:
----
shared int a = 0, b = 0;
// Thread 1:
a = 1;
b = 2;
// Thread 2:
writeln(a + b);
----
One might think that thread 2 cannot print "2", because from
the order of statements the numbers must be 0 + 0 or 1 + 0 or 1
+ 2. But thread 1 might execute `b = 2` before `a = 1`, because
the order doesn't matter to thread 1. So 0 + 2 is possible, too.
You're right, of course, and I shall do well to remember not to
think up examples for non-sequential code at such an hour, I am
sorry. Thank you for providing a correct example plus
explanation. The rest of my post still stands, though.
In recompense I shall provide another example, this one
translated from Wikipedia[1] instead:
__gshared int f = 0, x = 0;
// thread 1
while (f == 0);
// Memory barrier required here
writeln(x)
// thread 2
x = 42;
// Memory barrier required here
f = 1;
The above demonstrates a case where you do need a memory barrier:
thread 1 and 2 have a consumer/producer relationship, where
thread 1 wants to consume a value from thread 2 via `x`, using
`f` to be notified that `x` is ready to be consumed;
Without memory barriers at both of the indicated lines the cpu is
free to reorder either thread:
The first is required so that thread 1 doesn't get reordered to
consume before being notified and the second so that thread 2
doesn't get reordered to signal thread 1 before having produced.
If we had made `f` and `x` `shared` instead of `__gshared` the
spec would require (at least) the two indicated memory barriers
being emitted. Currently, though, it won't and for this case
(AFAIK) `shared` won't get you any benefit I'm aware of over
`__gshared`. You'll still need to add those memory barriers
(probably using inline assembler, though I'm not sure what's the
best way is in D, since I usually just stick with message
passing).
[1] https://en.wikipedia.org/wiki/Memory_barrier