Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.programming.threads > #269 > unrolled thread
| Started by | Masakuni Oishi <yamasa@bsdhouse.org> |
|---|---|
| First post | 2011-06-13 09:40 -0700 |
| Last post | 2011-06-15 02:06 -0700 |
| Articles | 20 on this page of 84 — 6 participants |
Back to article view | Back to comp.programming.threads
questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-13 09:40 -0700
Re: questions about memory_order_seq_cst fence Edek <edek.pienkowski@gmail.com> - 2011-06-13 22:39 +0200
Re: questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-14 08:27 -0700
Re: questions about memory_order_seq_cst fence Edek <edek.pienkowski@gmail.com> - 2011-06-16 00:21 +0200
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-15 15:48 -0700
Re: questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-16 05:03 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 08:35 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-16 12:05 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 11:19 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-16 13:57 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 13:51 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-16 16:53 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 16:17 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-16 17:37 +0200
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-16 08:47 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 16:54 +0100
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-16 09:01 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 17:07 +0100
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-16 13:59 -0700
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-16 14:32 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-17 08:03 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-17 16:19 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-17 15:40 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-30 14:26 +0200
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-17 15:24 -0700
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-18 03:49 -0700
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-18 14:40 -0700
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-18 15:46 -0700
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-18 20:27 -0700
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-18 21:31 -0700
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-18 21:37 -0700
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-20 15:45 -0700
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-20 20:05 -0700
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-18 14:06 +0200
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-16 18:32 +0200
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-16 15:42 -0700
Re: questions about memory_order_seq_cst fence Edek <edek.pienkowski@gmail.com> - 2011-07-10 19:47 +0200
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-16 08:51 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 17:23 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-16 18:49 +0200
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-16 08:51 -0700
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-16 17:25 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 16:56 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-18 14:28 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-20 09:54 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-20 15:39 +0200
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-22 13:24 +0200
Re: questions about memory_order_seq_cst fence Edek <edek.pienkowski@gmail.com> - 2011-06-16 14:39 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 13:55 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-16 12:03 +0200
Re: questions about memory_order_seq_cst fence Edek <edek.pienkowski@gmail.com> - 2011-07-10 19:10 +0200
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-13 16:00 -0700
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-13 23:31 -0700
Re: questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-14 08:32 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-14 23:05 +0100
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-14 16:44 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-15 08:34 +0100
Re: questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-15 02:11 -0700
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-15 15:58 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 08:26 +0100
Re: questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-16 05:05 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-16 13:11 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-18 15:42 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-20 09:27 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-20 15:30 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-20 15:00 +0100
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-21 14:54 +0200
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-21 18:37 +0200
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-21 15:59 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-22 09:01 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-20 15:41 +0100
Re: questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-20 23:24 -0700
Re: questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-22 10:46 -0700
Re: questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-22 11:19 -0700
Re: questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-22 11:57 -0700
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-27 14:05 +0200
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-29 16:14 -0700
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-06-24 01:42 -0700
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-06-27 13:24 +0200
Re: questions about memory_order_seq_cst fence Anthony Williams <anthony.ajw@gmail.com> - 2011-07-01 02:25 -0700
Re: questions about memory_order_seq_cst fence Alexander Terekhov <terekhov@web.de> - 2011-07-01 12:48 +0200
Re: questions about memory_order_seq_cst fence Masakuni Oishi <yamasa@bsdhouse.org> - 2011-06-15 01:53 -0700
Re: questions about memory_order_seq_cst fence Joshua Maurice <joshuamaurice@gmail.com> - 2011-06-15 02:57 -0700
Re: questions about memory_order_seq_cst fence "Chris M. Thomasson" <cristom@charter.net> - 2011-06-15 02:06 -0700
Page 1 of 5 [1] 2 3 4 5 Next page →
| From | Masakuni Oishi <yamasa@bsdhouse.org> |
|---|---|
| Date | 2011-06-13 09:40 -0700 |
| Subject | questions about memory_order_seq_cst fence |
| Message-ID | <43eb372b-6517-4914-b647-860f1f7136ba@k15g2000pri.googlegroups.com> |
Hi, I have some questions about C++0x memory model. /*** code 1 ***/ // Initially atomic<int> x(0), y(0); // Thread 1: y.store(1, memory_order_release); atomic_thread_fence(memory_order_seq_cst); r1 = x.load(memory_order_acquire); // Thread 2: x.store(1, memory_order_release); // Thread 3: r2 = x.load(memory_order_acquire); atomic_thread_fence(memory_order_seq_cst); r3 = y.load(memory_order_acquire); /***************/ In the above code, is r1 == 0 && r2 == 1 && r3 == 0 possible? I think it should be prohibited, but I couldn't make sure that from the C++0x FDIS. So I changed the memory_order of Thread 2 to seq_cst, like this: /*** code 2 ***/ // Initially atomic<int> x(0), y(0); // Thread 1: y.store(1, memory_order_release); atomic_thread_fence(memory_order_seq_cst); // (1) r1 = x.load(memory_order_acquire); // Thread 2: x.store(1, memory_order_seq_cst); // (3) // Thread 3: r2 = x.load(memory_order_acquire); atomic_thread_fence(memory_order_seq_cst); // (2) r3 = y.load(memory_order_acquire); /***************/ In code 2, r1 == 0 && r2 == 1 && r3 == 0 is not allowed. The proof is as follows: When (1) precedes (2) in S, r3 == 0 is not allowed (FDIS 29.3_6). When (2) precedes (1) in S, if r2 == 1 then (3) happens before (2), so (3) precedes (2) in S, therefore, (3) precedes (1) in S. Then, r1 == 0 is not allowed (FDIS 29.3_4). So, my questions are: For code 1, is r1 == 0 && r2 == 1 && r3 == 0 allowed in the C++0x FDIS? If it is, is there any real architecture which allows such result? -- masakuni
[toc] | [next] | [standalone]
| From | Edek <edek.pienkowski@gmail.com> |
|---|---|
| Date | 2011-06-13 22:39 +0200 |
| Message-ID | <it5sht$i7j$1@node2.news.atman.pl> |
| In reply to | #269 |
On 06/13/2011 06:40 PM, Masakuni Oishi wrote: > Hi, > > I have some questions about C++0x memory model. > > /*** code 1 ***/ > [snip a lot] I'm tired and I haven't followed the C++11 discussion, but are the fences relevant to the atomic operations themselves? I mean, aren't they for enforcing regular variables around atomics? Edek
[toc] | [prev] | [next] | [standalone]
| From | Masakuni Oishi <yamasa@bsdhouse.org> |
|---|---|
| Date | 2011-06-14 08:27 -0700 |
| Message-ID | <b7657dae-d49f-4859-8020-b5d76bfae2cd@p9g2000prh.googlegroups.com> |
| In reply to | #271 |
Edek <edek.pienkow...@gmail.com> wrote: > I'm tired and I haven't followed the C++11 discussion, > but are the fences relevant to the atomic operations > themselves? I mean, aren't they for enforcing regular > variables around atomics? The fences enforce ordering for not only regular variables but also atomic variables. For example: // Initially atomic<int> x(0), y(0); // Thread 1: y.store(1, memory_order_relaxed); x.store(1, memory_order_release); // Thread 2: r1 = x.load(memory_order_acquire); r2 = y.load(memory_order_relaxed); In this code, if r1 is 1, then r2 must be 1, not 0. -- masakuni
[toc] | [prev] | [next] | [standalone]
| From | Edek <edek.pienkowski@gmail.com> |
|---|---|
| Date | 2011-06-16 00:21 +0200 |
| Message-ID | <itbb7k$uhh$1@node2.news.atman.pl> |
| In reply to | #274 |
On 06/14/2011 05:27 PM, Masakuni Oishi wrote:
> Edek<edek.pienkow...@gmail.com> wrote:
>> I'm tired and I haven't followed the C++11 discussion,
>> but are the fences relevant to the atomic operations
>> themselves? I mean, aren't they for enforcing regular
>> variables around atomics?
>
> The fences enforce ordering for not only regular variables
> but also atomic variables.
> For example:
>
> // Initially
> atomic<int> x(0), y(0);
>
> // Thread 1:
> y.store(1, memory_order_relaxed); <--- this needn't be atomic,
it just happens to be
> x.store(1, memory_order_release); <---- This is like releasing a lock
so y store must be done earlier
>
> // Thread 2:
> r1 = x.load(memory_order_acquire); <--- This is like acquiring a lock
so y load must be done later
> r2 = y.load(memory_order_relaxed); <--- Might not be atomic
>
>
> In this code, if r1 is 1, then r2 must be 1, not 0.
>
> -- masakuni
Yes, that is what I actually meant (sorry, I'm a plain novice in this
weird atomic stuff). See my above small comments.
But what I also meant is the following, simplifying things
> // Thread 2:
> x.store(1, memory_order_release);
This seems not to enforce anything, if there is no code above it
in thread 2. Does it enforce anything (apart from atomicity
of write)?
(Quite antique these days) quote, from n2427
memory_order_release
Performs a release operation on the affected
memory locations, thus
making regular memory writes visible to other
threads through the atomic variable to which it is applied.
This, however, is a sequence point (interacts with thread 1's and
thread 2's fences):
> // Thread 2:
> x.store(1, memory_order_seq_cst); // (3)
Quote:
...in addition, has sequentially-consistent operation ordering.
So, if I understand this mail thread correctly, the question is whether
in the code 1 case from your question the change to x made by thread 2,
but - to my understanding - not really ordered in any way in code 1,
is visible by threads 1 and 3 in a specified order enforced by these
threads' (1 & 3) fences, or not necessarily (and y is just to show the
constraints - if we can look at it for a moment from this aspect).
Is everything above right, or is it more subtle?
Edek
PS.
As a side note, I compiled all ops on x86_64, and atomic<int>::load
is mfence/load/mfence even for relaxed. I'd need some time to analyse
the thing from perspective of other ops implementations in all
orderings, and this leads me to the not so subtle question:
I understand people _should definitely_ use the default.
I assume the goal, or the official word for it is 'rationale', was
to let people 'who understand' write code that would be both portable
and more efficient than the default. I am somehow beginning to doubt
both my capabilities and whether this will be at all possible - I mean
the efficiency, not portability (the latter can be simply done right).
Though maybe the bottom line is that at least the precise implementation
will have at least a couple of fences less than the default, at the
price of - I think no one argues about that - complexity.
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2011-06-15 15:48 -0700 |
| Message-ID | <c092d4f5-40b5-4872-a5cd-fdc19f618f82@z4g2000prk.googlegroups.com> |
| In reply to | #284 |
On Jun 15, 3:21 pm, Edek <edek.pienkow...@gmail.com> wrote:
> On 06/14/2011 05:27 PM, Masakuni Oishi wrote:
>
> > Edek<edek.pienkow...@gmail.com> wrote:
> >> I'm tired and I haven't followed the C++11 discussion,
> >> but are the fences relevant to the atomic operations
> >> themselves? I mean, aren't they for enforcing regular
> >> variables around atomics?
>
> > The fences enforce ordering for not only regular variables
> > but also atomic variables.
> > For example:
>
> > // Initially
> > atomic<int> x(0), y(0);
>
> > // Thread 1:
> > y.store(1, memory_order_relaxed); <--- this needn't be atomic,
>
> it just happens to be> x.store(1, memory_order_release); <---- This is like releasing a lock
>
> so y store must be done earlier
>
> > // Thread 2:
> > r1 = x.load(memory_order_acquire); <--- This is like acquiring a lock
>
> so y load must be done later
>
> > r2 = y.load(memory_order_relaxed); <--- Might not be atomic
>
> > In this code, if r1 is 1, then r2 must be 1, not 0.
>
> > -- masakuni
>
> Yes, that is what I actually meant (sorry, I'm a plain novice in this
> weird atomic stuff). See my above small comments.
>
> But what I also meant is the following, simplifying things
>
> > // Thread 2:
> > x.store(1, memory_order_release);
>
> This seems not to enforce anything, if there is no code above it
> in thread 2. Does it enforce anything (apart from atomicity
> of write)?
>
> (Quite antique these days) quote, from n2427
> memory_order_release
> Performs a release operation on the affected
> memory locations, thus
> making regular memory writes visible to other
> threads through the atomic variable to which it is applied.
>
> This, however, is a sequence point (interacts with thread 1's and
> thread 2's fences):
"Does it enforce anything (apart from atomicity > of write)?"
I'm pretty sure no. A store memory_order_release vs
memory_order_relaxed differs only in that it can provide additional
guarantees w.r.t. other actions in the same thread as the store.
Technically, that isn't quite true. The call which creates and starts
a thread synchronizes-with the first memory action in the thread
(30.3.1.2 thread constructors / 5), and the last memory action in a
thread synchronizes-with any join calls on that thread from other
threads (30.3.1.5 thread members / 5). Thus, the release could lead to
additional guarantees because of this synchronizes-with relation with
the start and end of the thread. However, there's no such relevant
operations in this example, so in this example that single memory
operation in thread 2 might as well be memory_order_relaxed AFAIK.
Moreover, I think you can argue similarly for the rest of the
memory_order_acquires and memory_order_releases. They might as well be
memory_order_relaxed. (The fences do matter if they're seq_cst or
something else, of course.)
> > // Thread 2:
> > x.store(1, memory_order_seq_cst); // (3)
>
> Quote:
> ...in addition, has sequentially-consistent operation ordering.
>
> So, if I understand this mail thread correctly, the question is whether
> in the code 1 case from your question the change to x made by thread 2,
> but - to my understanding - not really ordered in any way in code 1,
> is visible by threads 1 and 3 in a specified order enforced by these
> threads' (1 & 3) fences, or not necessarily (and y is just to show the
> constraints - if we can look at it for a moment from this aspect).
>
> Is everything above right, or is it more subtle?
That's about it. The question is:
For seq_cst fences X and Y, for atomic reads A and B on atomic object
M,
where
A sees the value from an atomic write C, and
B sees the value from an atomic write D (which may be the same as
C),
if
A is sequenced-before X, and
X precedes Y in the total order S on seq_cst operations, and
Y is sequenced-before B,
then
Can D precede C in the modification order of M?
I'm going to bring this to comp.lang.c++, and maybe comp.lang.c++
moderated and/or comp.std.c++.
> PS.
> As a side note, I compiled all ops on x86_64, and atomic<int>::load
> is mfence/load/mfence even for relaxed.
This is very wrong. At least, very counter to intent. What
implementation of C++0x threading are you using? Maybe it's a first
attempt implementation, and they're going to "fix" it later?
> I'd need some time to analyse
> the thing from perspective of other ops implementations in all
> orderings, and this leads me to the not so subtle question:
>
> I understand people _should definitely_ use the default.
> I assume the goal, or the official word for it is 'rationale', was
> to let people 'who understand' write code that would be both portable
> and more efficient than the default. I am somehow beginning to doubt
> both my capabilities and whether this will be at all possible - I mean
> the efficiency, not portability (the latter can be simply done right).
> Though maybe the bottom line is that at least the precise implementation
> will have at least a couple of fences less than the default, at the
> price of - I think no one argues about that - complexity.
This sounds very wrong.
[toc] | [prev] | [next] | [standalone]
| From | Masakuni Oishi <yamasa@bsdhouse.org> |
|---|---|
| Date | 2011-06-16 05:03 -0700 |
| Message-ID | <d9948ce2-c528-4c47-8681-4a1a25c02c31@z15g2000prn.googlegroups.com> |
| In reply to | #285 |
On Jun 16, Joshua Maurice <joshuamaur...@gmail.com> wrote: > On Jun 15, 3:21 pm, Edek <edek.pienkow...@gmail.com> wrote: > > So, if I understand this mail thread correctly, the question is whether > > in the code 1 case from your question the change to x made by thread 2, > > but - to my understanding - not really ordered in any way in code 1, > > is visible by threads 1 and 3 in a specified order enforced by these > > threads' (1 & 3) fences, or not necessarily (and y is just to show the > > constraints - if we can look at it for a moment from this aspect). > > > Is everything above right, or is it more subtle? > > That's about it. The question is: > > For seq_cst fences X and Y, for atomic reads A and B on atomic object > M, > where > A sees the value from an atomic write C, and > B sees the value from an atomic write D (which may be the same as > C), > if > A is sequenced-before X, and > X precedes Y in the total order S on seq_cst operations, and > Y is sequenced-before B, > then > Can D precede C in the modification order of M? Yes. In this topic, my concern is effects of seq_cst fence. So, please don't matter the difference between release/acquire and relaxed. -- masakuni
[toc] | [prev] | [next] | [standalone]
| From | Anthony Williams <anthony.ajw@gmail.com> |
|---|---|
| Date | 2011-06-16 08:35 +0100 |
| Message-ID | <87boxyfctc.fsf@justsoftwaresolutions.co.uk> |
| In reply to | #284 |
Edek <edek.pienkowski@gmail.com> writes: > As a side note, I compiled all ops on x86_64, and atomic<int>::load > is mfence/load/mfence even for relaxed. I'd need some time to analyse > the thing from perspective of other ops implementations in all > orderings, and this leads me to the not so subtle question: Ouch. That is a seriously over-cautious implementation. Atomics should not need any fences on x86_64 unless you actually write atomic_thread_fence(memory_order_seq_cst) See my blog entry for the required operations: http://www.justsoftwaresolutions.co.uk/threading/intel-memory-ordering-and-c++-memory-model.html The only one that is not a plain MOV is a seq_cst store, which is an XCHG. Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
[toc] | [prev] | [next] | [standalone]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-06-16 12:05 +0200 |
| Message-ID | <4DF9D581.E607BEB4@web.de> |
| In reply to | #288 |
Anthony Williams wrote: > > Edek <edek.pienkowski@gmail.com> writes: > > > As a side note, I compiled all ops on x86_64, and atomic<int>::load > > is mfence/load/mfence even for relaxed. I'd need some time to analyse > > the thing from perspective of other ops implementations in all > > orderings, and this leads me to the not so subtle question: > > Ouch. That is a seriously over-cautious implementation. Atomics should > not need any fences on x86_64 unless you actually write > atomic_thread_fence(memory_order_seq_cst) > > See my blog entry for the required operations: > > http://www.justsoftwaresolutions.co.uk/threading/intel-memory-ordering-and-c++-memory-model.html > > The only one that is not a plain MOV is a seq_cst store, which is an > XCHG. I believe that a seq_cst load is not a plain move either... regards, alexander.
[toc] | [prev] | [next] | [standalone]
| From | Anthony Williams <anthony.ajw@gmail.com> |
|---|---|
| Date | 2011-06-16 11:19 +0100 |
| Message-ID | <8739jaf59n.fsf@justsoftwaresolutions.co.uk> |
| In reply to | #290 |
Alexander Terekhov <terekhov@web.de> writes: > Anthony Williams wrote: >> >> Edek <edek.pienkowski@gmail.com> writes: >> >> > As a side note, I compiled all ops on x86_64, and atomic<int>::load >> > is mfence/load/mfence even for relaxed. I'd need some time to analyse >> > the thing from perspective of other ops implementations in all >> > orderings, and this leads me to the not so subtle question: >> >> Ouch. That is a seriously over-cautious implementation. Atomics should >> not need any fences on x86_64 unless you actually write >> atomic_thread_fence(memory_order_seq_cst) >> >> See my blog entry for the required operations: >> >> http://www.justsoftwaresolutions.co.uk/threading/intel-memory-ordering-and-c++-memory-model.html >> >> The only one that is not a plain MOV is a seq_cst store, which is an >> XCHG. > > I believe that a seq_cst load is not a plain move either... Why do think it shouldn't be, and what do you think it should be instead? The mapping in my blog post was confirmed by Intel processor engineers. Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
[toc] | [prev] | [next] | [standalone]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-06-16 13:57 +0200 |
| Message-ID | <4DF9EF9A.911CC74F@web.de> |
| In reply to | #291 |
Anthony Williams wrote: > > Alexander Terekhov <terekhov@web.de> writes: > > > Anthony Williams wrote: > >> > >> Edek <edek.pienkowski@gmail.com> writes: > >> > >> > As a side note, I compiled all ops on x86_64, and atomic<int>::load > >> > is mfence/load/mfence even for relaxed. I'd need some time to analyse > >> > the thing from perspective of other ops implementations in all > >> > orderings, and this leads me to the not so subtle question: > >> > >> Ouch. That is a seriously over-cautious implementation. Atomics should > >> not need any fences on x86_64 unless you actually write > >> atomic_thread_fence(memory_order_seq_cst) > >> > >> See my blog entry for the required operations: > >> > >> http://www.justsoftwaresolutions.co.uk/threading/intel-memory-ordering-and-c++-memory-model.html > >> > >> The only one that is not a plain MOV is a seq_cst store, which is an > >> XCHG. > > > > I believe that a seq_cst load is not a plain move either... > > Why do think it shouldn't be, Akin to what Jeffrey Yasskin said on your blog: http://www.justsoftwaresolutions.co.uk/threading/intel-memory-ordering-and-c++-memory-model.html "Do you happen to have a link to a proof that a plain mov is all that's needed for a sequentially-consistent load? I see from the memory model documents that the xchg'es all happen in a total order, and that movs won't be reordered across xchg, but I'm having trouble getting from there to sequential consistency. by Jeffrey Yasskin at 07:23:51 on Wednesday, 19 May 2010" Do *you* happen to have a link to a proof? > and what do you think it should be instead? http://www.decadent.org.uk/pipermail/cpp-threads/2008-December/001933.html "Load Seq_Cst: LOCK XADD(0) // alternative: MFENCE,MOV (from memory)" http://portal.acm.org/citation.cfm?id=1926394 "Sequentially consistent atomics The proposal above includes two implementations of sequentially consistent atomic reads and writes; one with the x86 locked instructions, and the other with fence instructions on both the reads and writes. However, we can prove that it suffices either to place an mfence before every sc read, or after every sc write, but that it is not necessary to do both. In practice, placing the fence after the sc writes is expected to yield higher performance." > > The mapping in my blog post was confirmed by Intel processor engineers. Without a proof? regards, alexander.
[toc] | [prev] | [next] | [standalone]
| From | Anthony Williams <anthony.ajw@gmail.com> |
|---|---|
| Date | 2011-06-16 13:51 +0100 |
| Message-ID | <87wrgm9bxk.fsf@justsoftwaresolutions.co.uk> |
| In reply to | #292 |
Alexander Terekhov <terekhov@web.de> writes: > Anthony Williams wrote: >> >> Alexander Terekhov <terekhov@web.de> writes: >> >> > Anthony Williams wrote: >> >> >> >> Edek <edek.pienkowski@gmail.com> writes: >> >> >> >> > As a side note, I compiled all ops on x86_64, and atomic<int>::load >> >> > is mfence/load/mfence even for relaxed. I'd need some time to analyse >> >> > the thing from perspective of other ops implementations in all >> >> > orderings, and this leads me to the not so subtle question: >> >> >> >> Ouch. That is a seriously over-cautious implementation. Atomics should >> >> not need any fences on x86_64 unless you actually write >> >> atomic_thread_fence(memory_order_seq_cst) >> >> >> >> See my blog entry for the required operations: >> >> >> >> http://www.justsoftwaresolutions.co.uk/threading/intel-memory-ordering-and-c++-memory-model.html >> >> >> >> The only one that is not a plain MOV is a seq_cst store, which is an >> >> XCHG. >> > >> > I believe that a seq_cst load is not a plain move either... >> >> Why do think it shouldn't be, > > Akin to what Jeffrey Yasskin said on your blog: > > http://www.justsoftwaresolutions.co.uk/threading/intel-memory-ordering-and-c++-memory-model.html > > "Do you happen to have a link to a proof that a plain mov is all that's > needed for a sequentially-consistent load? I see from the memory model > documents that the xchg'es all happen in a total order, and that movs > won't be reordered across xchg, but I'm having trouble getting from > there to sequential consistency. > > by Jeffrey Yasskin at 07:23:51 on Wednesday, 19 May 2010" > > Do *you* happen to have a link to a proof? LOCKed instructions have a total order (7.2.3.8 in my copy of the Intel 64 and IA-32 SDM Vol 3A), so if you use XCHG for stores (as per my blog post) then all processors/threads must agree on the order of the writes. This is the key to SC --- all SC stores must have a single total order which is agreed across all threads. Why do you think this is not enough? Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
[toc] | [prev] | [next] | [standalone]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-06-16 16:53 +0200 |
| Message-ID | <4DFA18D0.3A413EED@web.de> |
| In reply to | #297 |
Anthony Williams wrote: [...] > LOCKed instructions have a total order (7.2.3.8 in my copy of the Intel > 64 and IA-32 SDM Vol 3A), so if you use XCHG for stores (as per my blog > post) then all processors/threads must agree on the order of the writes. > > This is the key to SC --- all SC stores must have a single total order > which is agreed across all threads. > > Why do you think this is not enough? In x.store(44, memory_order_relaxed); // or _release r1 = y.load(memory_order_seq_cst); there should be a store-load reordering constraint, just like in x.store(44, memory_order_seq_cst); r1 = y.load(memory_order_relaxed); // or _acquire/_consume Implementation 1: Load Seq_Cst: LOCK XADD(0) Store Seq_Cst: LOCK XCHG Implementation 2: Load Seq_Cst: LOCK XADD(0) Store Seq_Cst: MOV, MFENCE Implementation 3: Load Seq_Cst: MFENCE, MOV Store Seq_Cst: LOCK XCHG Incorrect implementation Load Seq_Cst: MFENCE, MOV Store Seq_Cst: MOV, MFENCE is busted because IRIW won't work. regards, alexander.
[toc] | [prev] | [next] | [standalone]
| From | Anthony Williams <anthony.ajw@gmail.com> |
|---|---|
| Date | 2011-06-16 16:17 +0100 |
| Message-ID | <87oc1xajr3.fsf@justsoftwaresolutions.co.uk> |
| In reply to | #299 |
Alexander Terekhov <terekhov@web.de> writes: > Anthony Williams wrote: > [...] >> LOCKed instructions have a total order (7.2.3.8 in my copy of the Intel >> 64 and IA-32 SDM Vol 3A), so if you use XCHG for stores (as per my blog >> post) then all processors/threads must agree on the order of the writes. >> >> This is the key to SC --- all SC stores must have a single total order >> which is agreed across all threads. >> >> Why do you think this is not enough? > > x.store(44, memory_order_relaxed); // or _release > r1 = y.load(memory_order_seq_cst); > > there should be a store-load reordering constraint, just like in > > x.store(44, memory_order_seq_cst); > r1 = y.load(memory_order_relaxed); // or _acquire/_consume Why? Can you give an example that would be broken by the lack of such a constraint, and a reference to the FDIS that guarantees the presence of that constraint? Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
[toc] | [prev] | [next] | [standalone]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-06-16 17:37 +0200 |
| Message-ID | <4DFA2342.52931D8@web.de> |
| In reply to | #300 |
Anthony Williams wrote: > > Alexander Terekhov <terekhov@web.de> writes: > > > Anthony Williams wrote: > > [...] > >> LOCKed instructions have a total order (7.2.3.8 in my copy of the Intel > >> 64 and IA-32 SDM Vol 3A), so if you use XCHG for stores (as per my blog > >> post) then all processors/threads must agree on the order of the writes. > >> > >> This is the key to SC --- all SC stores must have a single total order > >> which is agreed across all threads. > >> > >> Why do you think this is not enough? > > > > x.store(44, memory_order_relaxed); // or _release > > r1 = y.load(memory_order_seq_cst); > > > > there should be a store-load reordering constraint, just like in > > > > x.store(44, memory_order_seq_cst); > > r1 = y.load(memory_order_relaxed); // or _acquire/_consume > > Why? Because the above is the same as x.store(44, memory_order_relaxed); // or _release atomic_thread_fence(memory_order_seq_cst); r1 = y.load(memory_order_relaxed); // or _acquire/_consume > Can you give an example that would be broken by the lack of such a > constraint, Any code written with the expectation that x.store(44, memory_order_relaxed); // or _release r1 = y.load(memory_order_seq_cst); and/or x.store(44, memory_order_seq_cst); r1 = y.load(memory_order_relaxed); // or _acquire/_consume is the same as x.store(44, memory_order_relaxed); // or _release atomic_thread_fence(memory_order_seq_cst); r1 = y.load(memory_order_relaxed); // or _acquire/_consume > and a reference to the FDIS that guarantees the presence of > that constraint? Do you have a reference to FDIS? (*&%*(&^$%&*(^_*(&+)(&*)&^978 http://groups.google.com/groups?threadm=4DF1EC53.29714FE9@web.de regards, alexander.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <cristom@charter.net> |
|---|---|
| Date | 2011-06-16 08:47 -0700 |
| Message-ID | <LzpKp.6673$x11.822@newsfe09.iad> |
| In reply to | #302 |
"Alexander Terekhov" <terekhov@web.de> wrote in message news:4DFA2342.52931D8@web.de... > > Anthony Williams wrote: >> >> Alexander Terekhov <terekhov@web.de> writes: >> >> > Anthony Williams wrote: >> > [...] >> >> LOCKed instructions have a total order (7.2.3.8 in my copy of the >> >> Intel >> >> 64 and IA-32 SDM Vol 3A), so if you use XCHG for stores (as per my >> >> blog >> >> post) then all processors/threads must agree on the order of the >> >> writes. >> >> >> >> This is the key to SC --- all SC stores must have a single total order >> >> which is agreed across all threads. >> >> >> >> Why do you think this is not enough? >> > >> > x.store(44, memory_order_relaxed); // or _release >> > r1 = y.load(memory_order_seq_cst); >> > >> > there should be a store-load reordering constraint, just like in >> > >> > x.store(44, memory_order_seq_cst); >> > r1 = y.load(memory_order_relaxed); // or _acquire/_consume >> >> Why? > > Because the above is the same as > > x.store(44, memory_order_relaxed); // or _release > atomic_thread_fence(memory_order_seq_cst); > r1 = y.load(memory_order_relaxed); // or _acquire/_consume > >> Can you give an example that would be broken by the lack of such a >> constraint, > > Any code written with the expectation that > > x.store(44, memory_order_relaxed); // or _release > r1 = y.load(memory_order_seq_cst); > > and/or > > x.store(44, memory_order_seq_cst); > r1 = y.load(memory_order_relaxed); // or _acquire/_consume I cannot think of exactly why the code above would not behave the same as the code below: > is the same as > > x.store(44, memory_order_relaxed); // or _release > atomic_thread_fence(memory_order_seq_cst); > r1 = y.load(memory_order_relaxed); // or _acquire/_consume Humm... [...]
[toc] | [prev] | [next] | [standalone]
| From | Anthony Williams <anthony.ajw@gmail.com> |
|---|---|
| Date | 2011-06-16 16:54 +0100 |
| Message-ID | <87k4clai0h.fsf@justsoftwaresolutions.co.uk> |
| In reply to | #302 |
Alexander Terekhov <terekhov@web.de> writes: > Anthony Williams wrote: >> >> Alexander Terekhov <terekhov@web.de> writes: >> >> > Anthony Williams wrote: >> > [...] >> >> LOCKed instructions have a total order (7.2.3.8 in my copy of the Intel >> >> 64 and IA-32 SDM Vol 3A), so if you use XCHG for stores (as per my blog >> >> post) then all processors/threads must agree on the order of the writes. >> >> >> >> This is the key to SC --- all SC stores must have a single total order >> >> which is agreed across all threads. >> >> >> >> Why do you think this is not enough? >> > >> > x.store(44, memory_order_relaxed); // or _release >> > r1 = y.load(memory_order_seq_cst); >> > >> > there should be a store-load reordering constraint, just like in >> > >> > x.store(44, memory_order_seq_cst); >> > r1 = y.load(memory_order_relaxed); // or _acquire/_consume >> >> Why? > > Because the above is the same as > > x.store(44, memory_order_relaxed); // or _release > atomic_thread_fence(memory_order_seq_cst); > r1 = y.load(memory_order_relaxed); // or _acquire/_consume No, it isn't. SC fences have very specific rules. This thread started by discussing these rules, and how they don't necessarily do what you might expect. Also, an SC load following a relaxed store does not impose any ordering constraints on that store, and neither does an SC store preceding a relaxed load impose any constraints on the load. All 3 bits of code above are thus different. For reference, 29.3p8 says: [ Note: memory_order_seq_cst ensures sequential consistency only for a program that is free of data races and uses exclusively memory_order_seq_cst operations. Any use of weaker ordering will invalidate this guarantee unless extreme care is used. In particular, memory_order_seq_cst fences ensure a total order only for the fences themselves. Fences cannot, in general, be used to restore sequential consistency for atomic operations with weaker ordering specifications. — end note ] i.e. you cannot replace an SC operation with a relaxed op and a fence and expect it to behave the same. >> Can you give an example that would be broken by the lack of such a >> constraint, > > Any code written with the expectation that > > x.store(44, memory_order_relaxed); // or _release > r1 = y.load(memory_order_seq_cst); > > is the same as > > x.store(44, memory_order_relaxed); // or _release > atomic_thread_fence(memory_order_seq_cst); > r1 = y.load(memory_order_relaxed); // or _acquire/_consume Can you give a specific example of such code? >> and a reference to the FDIS that guarantees the presence of >> that constraint? > > Do you have a reference to FDIS? (*&%*(&^$%&*(^_*(&+)(&*)&^978 > > http://groups.google.com/groups?threadm=4DF1EC53.29714FE9@web.de :-) If you can cite N3242, that will do in this case. The only changes to the concurrency section were those from N3278, and I don't think they materially affect this discussion. http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3242.pdf http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3278.htm Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <cristom@charter.net> |
|---|---|
| Date | 2011-06-16 09:01 -0700 |
| Message-ID | <hNpKp.4587$Z71.4302@newsfe21.iad> |
| In reply to | #306 |
"Anthony Williams" <anthony.ajw@gmail.com> wrote in message news:87k4clai0h.fsf@justsoftwaresolutions.co.uk... > Alexander Terekhov <terekhov@web.de> writes: > >> Anthony Williams wrote: [....] >>> Can you give an example that would be broken by the lack of such a >>> constraint, >> >> Any code written with the expectation that >> >> x.store(44, memory_order_relaxed); // or _release >> r1 = y.load(memory_order_seq_cst); >> >> is the same as >> >> x.store(44, memory_order_relaxed); // or _release >> atomic_thread_fence(memory_order_seq_cst); >> r1 = y.load(memory_order_relaxed); // or _acquire/_consume > > Can you give a specific example of such code? Perhaps in an SMR implementation. The author would be screwed if he/she thinks that the seq_cst load to `y' means that it will not be reordered with the preceding store to `x'.
[toc] | [prev] | [next] | [standalone]
| From | Anthony Williams <anthony.ajw@gmail.com> |
|---|---|
| Date | 2011-06-16 17:07 +0100 |
| Message-ID | <87boxxahfj.fsf@justsoftwaresolutions.co.uk> |
| In reply to | #308 |
"Chris M. Thomasson" <cristom@charter.net> writes: > "Anthony Williams" <anthony.ajw@gmail.com> wrote in message > news:87k4clai0h.fsf@justsoftwaresolutions.co.uk... >> Alexander Terekhov <terekhov@web.de> writes: >> >>> Anthony Williams wrote: > [....] >>>> Can you give an example that would be broken by the lack of such a >>>> constraint, >>> >>> Any code written with the expectation that >>> >>> x.store(44, memory_order_relaxed); // or _release >>> r1 = y.load(memory_order_seq_cst); >>> >>> is the same as >>> >>> x.store(44, memory_order_relaxed); // or _release >>> atomic_thread_fence(memory_order_seq_cst); >>> r1 = y.load(memory_order_relaxed); // or _acquire/_consume >> >> Can you give a specific example of such code? > > Perhaps in an SMR implementation. The author would be screwed if he/she > thinks that the seq_cst load to `y' means that it will not be reordered with > the preceding store to `x'. If you rely on things that aren't true, then you end up in a mess ;-) I'd better expand my question: Can you give an example of such code, along with reasoning based on the C++0x memory model to show that it is not broken? Anthony -- Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/ just::thread C++0x thread library http://www.stdthread.co.uk Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <cristom@charter.net> |
|---|---|
| Date | 2011-06-16 13:59 -0700 |
| Message-ID | <98uKp.16038$SG4.15177@newsfe03.iad> |
| In reply to | #309 |
"Anthony Williams" <anthony.ajw@gmail.com> wrote in message
news:87boxxahfj.fsf@justsoftwaresolutions.co.uk...
> "Chris M. Thomasson" <cristom@charter.net> writes:
>
>> "Anthony Williams" <anthony.ajw@gmail.com> wrote in message
>> news:87k4clai0h.fsf@justsoftwaresolutions.co.uk...
>>> Alexander Terekhov <terekhov@web.de> writes:
>>>
>>>> Anthony Williams wrote:
>> [....]
>>>>> Can you give an example that would be broken by the lack of such a
>>>>> constraint,
>>>>
>>>> Any code written with the expectation that
>>>>
>>>> x.store(44, memory_order_relaxed); // or _release
>>>> r1 = y.load(memory_order_seq_cst);
>>>>
>>>> is the same as
>>>>
>>>> x.store(44, memory_order_relaxed); // or _release
>>>> atomic_thread_fence(memory_order_seq_cst);
>>>> r1 = y.load(memory_order_relaxed); // or _acquire/_consume
>>>
>>> Can you give a specific example of such code?
>>
>> Perhaps in an SMR implementation. The author would be screwed if he/she
>> thinks that the seq_cst load to `y' means that it will not be reordered
>> with
>> the preceding store to `x'.
>
> If you rely on things that aren't true, then you end up in a mess ;-)
Touché! :^)
> I'd better expand my question:
>
> Can you give an example of such code, along with reasoning based on the
> C++0x memory model to show that it is not broken?
No. Quite frankly, it makes me want to use `std::memory_order_relaxed'
everywhere; ordering is provided by `std::atomic_thread_fence(...)'.
This better fuc%ing work!
_________________________________________________________
static std::atomic<int> g_var_1(0);
static std::atomic<int> g_var_2(0);
static std::atomic<int> g_sync(0);
void only_single_producer_in_process_lifetime()
{
g_var_1.store(1, std::memory_order_relaxed);
g_var_2.store(3, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
g_sync.store(1, std::memory_order_relaxed);
}
void many_consumers_in_process_lifetime()
{
while (! g_sync.load(std::memory_order_relaxed)) BACKOFF();
std::atomic_thread_fence(std::memory_order_seq_cst);
int var_1 = var_1.load(std::memory_order_relaxed);
int var_2 = var_2.load(std::memory_order_relaxed);
ASSERT((var_1 + var_2) == 4);
}
_________________________________________________________
:^O
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2011-06-16 14:32 -0700 |
| Message-ID | <2671e224-80a9-4e11-a224-64240676069f@y27g2000prb.googlegroups.com> |
| In reply to | #313 |
On Jun 16, 1:59 pm, "Chris M. Thomasson" <cris...@charter.net> wrote:
> "Anthony Williams" <anthony....@gmail.com> wrote in message
>
> news:87boxxahfj.fsf@justsoftwaresolutions.co.uk...
>
>
>
>
>
>
>
>
>
> > "Chris M. Thomasson" <cris...@charter.net> writes:
>
> >> "Anthony Williams" <anthony....@gmail.com> wrote in message
> >>news:87k4clai0h.fsf@justsoftwaresolutions.co.uk...
> >>> Alexander Terekhov <terek...@web.de> writes:
>
> >>>> Anthony Williams wrote:
> >> [....]
> >>>>> Can you give an example that would be broken by the lack of such a
> >>>>> constraint,
>
> >>>> Any code written with the expectation that
>
> >>>> x.store(44, memory_order_relaxed); // or _release
> >>>> r1 = y.load(memory_order_seq_cst);
>
> >>>> is the same as
>
> >>>> x.store(44, memory_order_relaxed); // or _release
> >>>> atomic_thread_fence(memory_order_seq_cst);
> >>>> r1 = y.load(memory_order_relaxed); // or _acquire/_consume
>
> >>> Can you give a specific example of such code?
>
> >> Perhaps in an SMR implementation. The author would be screwed if he/she
> >> thinks that the seq_cst load to `y' means that it will not be reordered
> >> with
> >> the preceding store to `x'.
>
> > If you rely on things that aren't true, then you end up in a mess ;-)
>
> Touché! :^)
>
> > I'd better expand my question:
>
> > Can you give an example of such code, along with reasoning based on the
> > C++0x memory model to show that it is not broken?
>
> No. Quite frankly, it makes me want to use `std::memory_order_relaxed'
> everywhere; ordering is provided by `std::atomic_thread_fence(...)'.
>
> This better fuc%ing work!
> _________________________________________________________
> static std::atomic<int> g_var_1(0);
> static std::atomic<int> g_var_2(0);
> static std::atomic<int> g_sync(0);
>
> void only_single_producer_in_process_lifetime()
> {
> g_var_1.store(1, std::memory_order_relaxed);
> g_var_2.store(3, std::memory_order_relaxed);
> std::atomic_thread_fence(std::memory_order_seq_cst);
> g_sync.store(1, std::memory_order_relaxed);
>
> }
>
> void many_consumers_in_process_lifetime()
> {
> while (! g_sync.load(std::memory_order_relaxed)) BACKOFF();
> std::atomic_thread_fence(std::memory_order_seq_cst);
> int var_1 = var_1.load(std::memory_order_relaxed);
> int var_2 = var_2.load(std::memory_order_relaxed);
> ASSERT((var_1 + var_2) == 4);}
AFAIK, the fences don't need to be seq_cst. This all works out with
just acquire and load fences.
29.8/2- For release fence A, acquire fence B, atomic write X on M,
atomic read Y on M:
If (A <sequence X) and (Y <sequence B) and (Y sees release-
seq(X)), then (A <sync B).
The producer's fence is sequenced before g_sync.store, and
g_sync.load is sequenced before the consumer's fence, and
and (eventually) g_sync.load sees a value from a write in the release
sequence of g_sync.store.
Therefore the producer's fence synchronizes-with the consumer's fence
(29.8/2).
Therefore with repeated application of 1.10/11 and 1.10/12, we can
conclude that
g_var_1.store happens-before g_var_1.load, and
g_var_2.store happens-before g_var_2.load.
Therefore with 1.10/18 we can conclude that
g_var_1.load sees g_var_1.store or a later write in the
modification order, and
g_var_2.load sees g_var_2.store or a later write in the
modification order.
There are no writes later than g_var_1.store in its modification
order, and same for g_var_2, and thus g_var_1.load sees g_var_1.store,
and g_var_2.load sees g_var_2.store. And thus the assert will not
fire.
Btw, the rule 29.8/2 is what I was taught as the meaning of "read" and
"write" barriers according to whatever Linux kernel documentation is
floating around on google. That still works, but of course there's a
lot more rules than can be applied on top of that now.
----
I was thinking we might be able to do something with:
For atomic operations A, B on atomic object M. For seq_cst fences X
and Y.
29.3/6- For read B, write A:
If (A <sequence X) and (X <S Y) and (Y <sequence B), then (B sees
mod-M[A, ...)).
But I haven't thought hard enough about it. We'd need to prove that
the producer's fence precedes the consumer's fence in the total order
S, and I'm not sure we could do that in this case.
----
This is another reason that I'm feeling a little miffed about seq_cst.
Sometimes seq_cst fences don't need seq_cst reads and writes to be
more than acq_rel fences. Sometimes they do need seq_cst reads and
writes to be more than acq_rel fences.
Here's what I've been able to parse on the subject of seq_cst fences.
For atomic operations A, B on atomic object M. For seq_cst fences X
and Y.
29.3/4- For read B, seq_cst write A:
If (A <S X) and (X <sequence B), then (B sees mod-M[A, ...)).
29.3/5- For seq_cst read B, write A:
If (A <sequence X) and (X <S B), then (B sees mod-M[A, ...)).
29.3/6- For read B, write A:
If (A <sequence X) and (X <S Y) and (Y <sequence B), then (B sees
mod-M[A, ...)).
29.3/7- For writes A and B:
If (A <sequence X) and (X <S Y) and (Y <sequence B), then (A <mod-
M B).
The first concerns a relaxed (or better) read and a seq_cst write.
The second concerns a seq_cst read and a relaxed (or better) write.
The third concerns a relaxed (or better) read and a relaxed (or
better) write.
The fourth concerns two relaxed (or better) writes.
seq_cst fences seem to give no guarantees for two non-seq_cst reads.
At least, seq_cst fences gives no additional guarantees w.r.t. two non-
seq_cst reads above and beyond the guarantees of acq_rel fences. At
least, that's what I'm reading now. Considering I only really started
looking at this the other day, take with great warning please.
[toc] | [prev] | [next] | [standalone]
Page 1 of 5 [1] 2 3 4 5 Next page →
Back to top | Article view | comp.programming.threads
csiph-web