Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.programming.threads > #269 > unrolled thread

questions about memory_order_seq_cst fence

Started byMasakuni Oishi <yamasa@bsdhouse.org>
First post2011-06-13 09:40 -0700
Last post2011-06-15 02:06 -0700
Articles 20 on this page of 84 — 6 participants

Back to article view | Back to comp.programming.threads


Contents

  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 →


#269 — questions about memory_order_seq_cst fence

FromMasakuni Oishi <yamasa@bsdhouse.org>
Date2011-06-13 09:40 -0700
Subjectquestions 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]


#271

FromEdek <edek.pienkowski@gmail.com>
Date2011-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]


#274

FromMasakuni Oishi <yamasa@bsdhouse.org>
Date2011-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]


#284

FromEdek <edek.pienkowski@gmail.com>
Date2011-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]


#285

FromJoshua Maurice <joshuamaurice@gmail.com>
Date2011-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]


#294

FromMasakuni Oishi <yamasa@bsdhouse.org>
Date2011-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]


#288

FromAnthony Williams <anthony.ajw@gmail.com>
Date2011-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]


#290

FromAlexander Terekhov <terekhov@web.de>
Date2011-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]


#291

FromAnthony Williams <anthony.ajw@gmail.com>
Date2011-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]


#292

FromAlexander Terekhov <terekhov@web.de>
Date2011-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]


#297

FromAnthony Williams <anthony.ajw@gmail.com>
Date2011-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]


#299

FromAlexander Terekhov <terekhov@web.de>
Date2011-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]


#300

FromAnthony Williams <anthony.ajw@gmail.com>
Date2011-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]


#302

FromAlexander Terekhov <terekhov@web.de>
Date2011-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]


#303

From"Chris M. Thomasson" <cristom@charter.net>
Date2011-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]


#306

FromAnthony Williams <anthony.ajw@gmail.com>
Date2011-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]


#308

From"Chris M. Thomasson" <cristom@charter.net>
Date2011-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]


#309

FromAnthony Williams <anthony.ajw@gmail.com>
Date2011-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]


#313

From"Chris M. Thomasson" <cristom@charter.net>
Date2011-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]


#314

FromJoshua Maurice <joshuamaurice@gmail.com>
Date2011-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