www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - No memory model

reply "qznc" <qznc web.de> writes:
As far as I google, D has not specified a memory model.

However, I assume it should basically be the same as the C++ 
memory model: Sequential consistency for data-race-free programs.
Oct 21 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Monday, 21 October 2013 at 20:50:28 UTC, qznc wrote:
 As far as I google, D has not specified a memory model.

 However, I assume it should basically be the same as the C++ 
 memory model: Sequential consistency for data-race-free 
 programs.
shared = sequential consistency. immutable = immutable. TL = do whatever you want to make my program faster.
Oct 21 2013
parent reply "qznc" <qznc web.de> writes:
On Tuesday, 22 October 2013 at 00:26:48 UTC, deadalnix wrote:
 On Monday, 21 October 2013 at 20:50:28 UTC, qznc wrote:
 As far as I google, D has not specified a memory model.

 However, I assume it should basically be the same as the C++ 
 memory model: Sequential consistency for data-race-free 
 programs.
shared = sequential consistency. immutable = immutable. TL = do whatever you want to make my program faster.
So Ds shared has a similar effect as Javas volatile. The difference is transitivity like with const. Nevertheless, core.atomic also plays into this. Why do we need atomicStore, if we have shared? Why does atomicStore require its argument to be shared?
Oct 22 2013
next sibling parent reply "Moritz Maxeiner" <moritz ucworks.org> writes:
On Tuesday, 22 October 2013 at 09:07:38 UTC, qznc wrote:
 On Tuesday, 22 October 2013 at 00:26:48 UTC, deadalnix wrote:
 On Monday, 21 October 2013 at 20:50:28 UTC, qznc wrote:
 As far as I google, D has not specified a memory model.

 However, I assume it should basically be the same as the C++ 
 memory model: Sequential consistency for data-race-free 
 programs.
shared = sequential consistency. immutable = immutable. TL = do whatever you want to make my program faster.
So Ds shared has a similar effect as Javas volatile. The difference is transitivity like with const. Nevertheless, core.atomic also plays into this. Why do we need atomicStore, if we have shared? Why does atomicStore require its argument to be shared?
Without wanting to directly contradict he previous response(s), as far as I understand the documentation (http://dlang.org/migrate-to-shared.html#shared), the shared keyword guarantees only the following for a variable: - it goes into global storage, not thread-local one - it's effects of being shared are transitive Sequential consistency would - afaik - mean, that executing the threads of a nonsequential program in *any* interleaved order on a single processor in the relative order the program specifies for each thread internally would yield the same results as executing it in a true non-sequential environment, such as each thread being executed by one processor without any necessary interleaving. Again, as far as I understand the concept, it you truly had sequential consistency, you would not need atomic operations, but I don't think marking a variable as "shared" would really provide that, because then the compiler would need to inject locks for every shared variable and use them for all read/writes of that variable. So as far as I can see it "shared" does not prevent two threads from writing at the same time / reading/writing at the same time the same way as "volatile" does not do it for Java. This means you still need to provide correct synchronisation with via locking / lock-free algorithms; also, don't forget __gshared which only guarantees the variable goes into global storage, nothing more, so you definiely need atmic operations there for non-sequential programs. Anyway, if I'm wrong, please do correct me here, because I patched this together from the documentation, which I find somewhat thin at a few parts regarding this subject.
Oct 22 2013
parent reply "qznc" <qznc web.de> writes:
On Tuesday, 22 October 2013 at 10:06:54 UTC, Moritz Maxeiner 
wrote:
 Sequential consistency would - afaik - mean, that executing the 
 threads of a nonsequential program in *any* interleaved order 
 on a single processor in the relative order the program 
 specifies for each thread internally would yield the same 
 results as executing it in a true non-sequential environment, 
 such as each thread being executed by one processor without any 
 necessary interleaving.

 Again, as far as I understand the concept, it you truly had 
 sequential consistency, you would not need atomic operations, 
 but I don't think marking a variable as "shared" would really 
 provide that, because then the compiler would need to inject 
 locks for every shared variable and use them for all 
 read/writes of that variable.
You are a little bit off. Sequential consistency (SC) does require the compiler to insert locking. Initially: x = y = 0 thread 1 | thread 2 x = 1; | if (y == 2) y = 2; | assert (x == 1) SC guarantees that the assert succeed or is not executed due to the if-statement. Without SC, the assignments of thread 1 might be seen in a different order from thread 2, which means there is a point in time, where y==2 && x==0.
Oct 22 2013
parent reply "qznc" <qznc web.de> writes:
On Tuesday, 22 October 2013 at 10:44:41 UTC, qznc wrote:
 You are a little bit off. Sequential consistency (SC) does 
 require the compiler to insert locking.
Arg. Does NOT require the compiler to insert locking. ;)
Oct 22 2013
parent reply "Moritz Maxeiner" <moritz ucworks.org> writes:
On Tuesday, 22 October 2013 at 10:45:29 UTC, qznc wrote:
 On Tuesday, 22 October 2013 at 10:44:41 UTC, qznc wrote:
 You are a little bit off. Sequential consistency (SC) does 
 require the compiler to insert locking.
Arg. Does NOT require the compiler to insert locking. ;)
Alright, I more or less paraphrased the definition of SC (allegedly) made by Lamport, which is given on the Wikipedia page (http://en.wikipedia.org/wiki/Sequential_consistency), but in this case you answered your own question, I think. If SC does only guarantee this, then you'd need the atomic operations for correct synchronisation, as SC doesn't guarantee it?
Oct 22 2013
next sibling parent "qznc" <qznc web.de> writes:
On Tuesday, 22 October 2013 at 12:46:16 UTC, Moritz Maxeiner 
wrote:
 On Tuesday, 22 October 2013 at 10:45:29 UTC, qznc wrote:
 On Tuesday, 22 October 2013 at 10:44:41 UTC, qznc wrote:
 You are a little bit off. Sequential consistency (SC) does 
 require the compiler to insert locking.
Arg. Does NOT require the compiler to insert locking. ;)
Alright, I more or less paraphrased the definition of SC (allegedly) made by Lamport, which is given on the Wikipedia page (http://en.wikipedia.org/wiki/Sequential_consistency), but in this case you answered your own question, I think. If SC does only guarantee this, then you'd need the atomic operations for correct synchronisation, as SC doesn't guarantee it?
The usual phrase is "sequential consistency for data-race-free programs". The advice for unaware programmers is to avoid race conditions and properly synchronize everything with locks. Only then you get SC. My example contains a data-race, hence no SC (according to Java and C++ memory models). If you really want to write such code, then you must understand the whole complexity of the memory model. Then you can figure out, if the behavior of your program is defined by language semantics. In my example, the memory models says "undefined behavior". If you make the necessary changes (atomic operations, memory fences, etc), then the memory model says "defined behavior: you might get pass the assert successfully or not at all".
Oct 22 2013
prev sibling parent "qznc" <qznc web.de> writes:
On Tuesday, 22 October 2013 at 12:46:16 UTC, Moritz Maxeiner
wrote:
 On Tuesday, 22 October 2013 at 10:45:29 UTC, qznc wrote:
 On Tuesday, 22 October 2013 at 10:44:41 UTC, qznc wrote:
 You are a little bit off. Sequential consistency (SC) does 
 require the compiler to insert locking.
Arg. Does NOT require the compiler to insert locking. ;)
Alright, I more or less paraphrased the definition of SC (allegedly) made by Lamport, which is given on the Wikipedia page (http://en.wikipedia.org/wiki/Sequential_consistency), but in this case you answered your own question, I think. If SC does only guarantee this, then you'd need the atomic operations for correct synchronisation, as SC doesn't guarantee it?
The usual phrase is "sequential consistency for data-race-free programs". The advice for unaware programmers is to avoid race conditions and properly synchronize everything with locks. Only then you get SC. My example contains a data-race, hence no SC (according to Java and C++ memory models). If you really want to write such code, then you must understand the whole complexity of the memory model. Then you can figure out, if the behavior of your program is defined by language semantics. In my example, the memory models says "undefined behavior". If you make the necessary changes (atomic operations, memory fences, etc), then the memory model says "defined behavior: you might get pass the assert successfully or not at all".
Oct 22 2013
prev sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Tuesday, 22 October 2013 at 09:07:38 UTC, qznc wrote:
 On Tuesday, 22 October 2013 at 00:26:48 UTC, deadalnix wrote:
 On Monday, 21 October 2013 at 20:50:28 UTC, qznc wrote:
 As far as I google, D has not specified a memory model.

 However, I assume it should basically be the same as the C++ 
 memory model: Sequential consistency for data-race-free 
 programs.
shared = sequential consistency. immutable = immutable. TL = do whatever you want to make my program faster.
So Ds shared has a similar effect as Javas volatile. The difference is transitivity like with const.
Yes.
 Nevertheless, core.atomic also plays into this. Why do we need 
 atomicStore, if we have shared? Why does atomicStore require 
 its argument to be shared?
Several reasons. - Interoperability with C/C++, that do not understand shared. - Relaxed atomics. - DMD do not emit correct codegen for shared.
Oct 22 2013