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


Groups > comp.programming.threads > #1786

Re: forcing the compiler to reload from memory with c++0x

From frege <gottlobfrege@gmail.com>
Newsgroups comp.programming.threads
Subject Re: forcing the compiler to reload from memory with c++0x
Date 2011-01-28 19:43 -0800
Organization http://groups.google.com
Message-ID <c2c5e094-4b11-4cb7-bbec-db38a00c2f85@s3g2000vbf.googlegroups.com> (permalink)
References (3 earlier) <4D40A4C7.16E6F9AE@web.de> <69d82db7-34be-4de7-86c4-2f39cc1e6df3@m13g2000yqb.googlegroups.com> <aebb655b-6821-4c19-a170-71633273366c@k32g2000vbn.googlegroups.com> <cd471590-cf8d-4830-b6fb-38aa2b7d4f30@h16g2000yqh.googlegroups.com> <87ipx9xxc0.fsf@justsoftwaresolutions.co.uk>

Show all headers | View raw


On Jan 28, 3:10 am, Anthony Williams <anthony....@gmail.com> wrote:
> frege <gottlobfr...@gmail.com> writes:
>
> > I'm saying that volatile is all that is needed in this situation.
> > Possibly depending on what the proper definition of volatile (and
> > memory) is.  But in particular, fences and memory ordering are NOT
> > needed.  And that this is rare in threading.  Typically volatile isn't
> > very useful with threads, and novices think it is.  This is a counter-
> > example.
>
> No, it isn't. Under C++0x, volatile still has nothing to do with
> threading. If you rely on volatile to have one thread read data written
> by another then you have a "data race" and undefined behaviour. You need
> atomic operations, even if they are memory_order_relaxed.
>

I'll try to keep it short, since I have similar responses elsewhere in
this thread.
Basically, prior to C++0x I would have used volatile (+ aligned int)
as the closest approximation to what was required here - avoid having
the value cached forever (ie in register or whatever) but avoid memory
barriers.

With C++0x it looks like I would use atomic<int> with
memory_order_relaxed.
I wonder if anyone has described/explained how that is subtly
different than a normal int, even an aligned one.

There may be an additional point of interest in the example:
I'm not exactly sure of the wording/def'n of "data race" in C++0x, but
I'd be interested to know if there is technically a data race in the
example, because I think the algorithm *should* work.  If it
technically could be seen as a data race, and thus undefined
behaviour, I think the defn of data race needs to be looked at.  I
don't think there are issues, but it is an interesting example that
skirts the edge of many issues.

>
> > [....0000XXXXXX0000.....]
>
>
> No, you need atomic<int> with memory_order_relaxed operations and
> atomic_signal_fence() to prevent compiler reorderings.

I'm not sure there are any compiler reordering issues in this
example.  In particular, where would the fences go?!

> However, if the
> value in the queue implies that other data written by the pushing thread
> can be read by the popping thread (e.g. if the value in the queue is a
> pointer to the data) then you will need fences or non-relaxed operations
> to ensure that this other data is visible to the popping thread (even
> with atomic_signal_fence(), relaxed operations can become visible to
> other threads out of order). This is particularly important if the other
> data is written with non-atomic writes, since otherwise you have a data
> race and undefined behaviour again.
>

Yes, the example is very specific - the data in the buffer is ints,
not pointers.  In the document referenced by the OP, they mention the
need for additional non-relaxed operations when the data consists of
pointers (or equivalent - ie indexes into another array, etc).


> > And back to my original thoughts - looking at this example, does it
> > shed any insight into compiler optimizations, threading, visibility,
> > etc.  In particular, how long can the reader see 0 "after" the writer
> > has issued its write of X.  
>
> "within a reasonable period of time". i.e. it can't cache the value forever.
>

For some def'n of reasonable - see my comparison to copyright
extensions else-thread.

> > Without a memory_order_... could it never
> > see X? More precisely - has anything changed in this regard, compared
> > to before C++ had a memory model.  I think you are saying no, but I'm
> > wondering if old compilers were working based on general "unwritten"
> > rules (particularly since threading wasn't a C++ rule), but now that
> > the rules are clear, will they eventually stretch the rules farther
> > than they previously had?
>
> That is probably true in principle. Whereas before, compilers were
> probably restricting themselves so that atomic accesses could be written
> with plain variables (possible adorned with volatile), with C++0x they
> know that writes to non-atomic variables do not have to be made visible
> until an atomic operation with memory_order_release or stronger ordering
> occurs, or some other synchronization event such as a mutex lock.
>
> In practice, I expect that newer versions of existing compilers will try
> to ensure that code that worked with the older version will still work
> with the new version.
>

agreed.

> Anthony
> --

Thanks for the added clarity.  I now see atomics with relaxed ordering
as the new, *well defined* inter-thread "volatile", that was rarely
but occasionally needed pre-C++0x. (rare as it was very rarely
necessary or sufficient)

Tony

Back to comp.programming.threads | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Re: forcing the compiler to reload from memory with c++0x frege <gottlobfrege@gmail.com> - 2011-01-27 21:34 -0800
  Re: forcing the compiler to reload from memory with c++0x frege <gottlobfrege@gmail.com> - 2011-01-28 19:43 -0800
    Re: forcing the compiler to reload from memory with c++0x Anthony Williams <anthony.ajw@gmail.com> - 2011-01-30 22:07 +0000
  Re: forcing the compiler to reload from memory with c++0x Anthony Williams <anthony.ajw@gmail.com> - 2011-01-28 08:10 +0000
    Re: forcing the compiler to reload from memory with c++0x Dmitriy Vyukov <dvyukov@gmail.com> - 2011-01-28 00:45 -0800
      Re: forcing the compiler to reload from memory with c++0x Anthony Williams <anthony.ajw@gmail.com> - 2011-01-28 09:31 +0000
  Re: forcing the compiler to reload from memory with c++0x Dmitriy Vyukov <dvyukov@gmail.com> - 2011-01-28 00:09 -0800
    Re: forcing the compiler to reload from memory with c++0x Alexander Terekhov <terekhov@web.de> - 2011-01-29 15:49 +0100
      Re: forcing the compiler to reload from memory with c++0x Andy Venikov <swojchelowek@gmail.com> - 2011-01-31 15:53 -0500
    Re: forcing the compiler to reload from memory with c++0x frege <gottlobfrege@gmail.com> - 2011-01-28 19:28 -0800
      Re: forcing the compiler to reload from memory with c++0x Dmitriy Vyukov <dvyukov@gmail.com> - 2011-01-29 01:41 -0800

csiph-web