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


Groups > comp.lang.c > #96367 > unrolled thread

compound assignment to atomic type

Started byspacewar@gmail.com
First post2016-11-10 19:34 -0800
Last post2016-11-15 10:42 -0800
Articles 14 — 6 participants

Back to article view | Back to comp.lang.c


Contents

  compound assignment to atomic type spacewar@gmail.com - 2016-11-10 19:34 -0800
    Re: compound assignment to atomic type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-11 16:04 +0000
      Re: compound assignment to atomic type supercat@casperkitty.com - 2016-11-11 09:01 -0800
        Re: compound assignment to atomic type Tim Rentsch <txr@alumni.caltech.edu> - 2016-11-15 10:54 -0800
      Re: compound assignment to atomic type spacewar@gmail.com - 2016-11-12 00:48 -0800
        Re: compound assignment to atomic type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-12 11:06 +0000
          Re: compound assignment to atomic type supercat <flatfinger@casperkitty.com> - 2016-11-12 11:03 -0800
          Re: compound assignment to atomic type Tim Rentsch <txr@alumni.caltech.edu> - 2016-11-13 10:57 -0800
        Re: compound assignment to atomic type Tim Rentsch <txr@alumni.caltech.edu> - 2016-11-13 10:31 -0800
    Re: compound assignment to atomic type "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-11-12 11:24 -0800
      Re: compound assignment to atomic type Tim Rentsch <txr@alumni.caltech.edu> - 2016-11-13 10:59 -0800
        Re: compound assignment to atomic type "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-11-13 17:34 -0800
          Re: compound assignment to atomic type "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-11-13 17:48 -0800
          Re: compound assignment to atomic type Tim Rentsch <txr@alumni.caltech.edu> - 2016-11-15 10:42 -0800

#96367 — compound assignment to atomic type

Fromspacewar@gmail.com
Date2016-11-10 19:34 -0800
Subjectcompound assignment to atomic type
Message-ID<c023fb24-93f5-463d-8618-e19499f78f0a@googlegroups.com>
I'm confused about C11 compound assignments with E1 (left hand side) being an atomic type.

§6.5.16.2 ¶3 states:
    If E1 has an atomic type, compound assignment is a
    read-modify-write operation with memory_order_seq_cst memory order
    semantics.

Footnote 113 says
    Where a pointer to an atomic object can be formed and E1 and E2 have
    integer type, this is equivalent to the following code sequence [...]"
with the code sequence using atomic_compare_exchange_strong().

On the other hand, §7.17.7.5 ¶5 states:
    NOTE The operation of the atomic_fetch and modify generic functions are
    nearly equivalent to the operation of the corresponding op= compound
    assignment operators. The only differences are that the compound
    assignment operators are not guaranteed to operate atomically, [...]

Doesn't that directly contradict §6.5.16.2 ¶3 and footnote 113?

GCC 6.2.1 generates atomic RMW code for compound assignments with atomic LHS, but the NOTE in §7.17.7.5 makes me worry about that being non-portable.

[toc] | [next] | [standalone]


#96383

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-11-11 16:04 +0000
Message-ID<8737iyovea.fsf@bsb.me.uk>
In reply to#96367
spacewar@gmail.com writes:

> I'm confused about C11 compound assignments with E1 (left hand side)
> being an atomic type.
>
> §6.5.16.2 ¶3 states:
>     If E1 has an atomic type, compound assignment is a
>     read-modify-write operation with memory_order_seq_cst memory order
>     semantics.
>
> Footnote 113 says
>     Where a pointer to an atomic object can be formed and E1 and E2 have
>     integer type, this is equivalent to the following code sequence [...]"
> with the code sequence using atomic_compare_exchange_strong().
>
> On the other hand, §7.17.7.5 ¶5 states:
>     NOTE The operation of the atomic_fetch and modify generic functions are
>     nearly equivalent to the operation of the corresponding op= compound
>     assignment operators. The only differences are that the compound
>     assignment operators are not guaranteed to operate atomically, [...]
>
> Doesn't that directly contradict §6.5.16.2 ¶3 and footnote 113?

This came up in a DR about the use of various terms relating to atomic
types and atomic operations:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_486

> GCC 6.2.1 generates atomic RMW code for compound assignments with
> atomic LHS, but the NOTE in §7.17.7.5 makes me worry about that being
> non-portable.

The DR is under review, but I get the feeling the committee agrees that
the wording is confusing.  I think you can rely on x <op>= y having the
RMW sematics described in 6.5.16.2 (along with the extensive footnote
113).

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#96390

Fromsupercat@casperkitty.com
Date2016-11-11 09:01 -0800
Message-ID<d41c2041-75f0-44ea-b64f-576e8a0f64d1@googlegroups.com>
In reply to#96383
On Friday, November 11, 2016 at 10:04:38 AM UTC-6, Ben Bacarisse wrote:
> This came up in a DR about the use of various terms relating to atomic
> types and atomic operations:
> 
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_486

I'm not sure why the authors seem to have trouble with the idea that
implementations which don't meet certain common-but-possibly-not-universal
requirements (e.g. use of two's-complement arithmetic) would be unable to
support the optional threading features.  I'm also not clear what the author
of the Standard finds unclear about the notion that atomic pointer operations
may yield invalid pointers but would otherwise have defined behavior; the
obvious sensible meaning would be that an atomic operation on any type will
never do anything other than change some, all, or none of the bits in the
storage associated therewith.  The resulting pattern of bits may or may
not be meaningful, but the requested atomic operation will never have any
other effect.

It may also be helpful to have a Standard make clear that atomically adding
or subtracting any combination of displacements to a pointer, in any order,
will be equivalent to adding or subtracting the mathematical sum of those
displacements, without regard for whether intermediate values would be valid
pointers.

[toc] | [prev] | [next] | [standalone]


#96628

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-11-15 10:54 -0800
Message-ID<kfninrosheo.fsf@x-alumni2.alumni.caltech.edu>
In reply to#96390
supercat@casperkitty.com writes:

> On Friday, November 11, 2016 at 10:04:38 AM UTC-6, Ben Bacarisse wrote:
>> This came up in a DR about the use of various terms relating to atomic
>> types and atomic operations:
>>
>> http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_486
>
> I'm not sure why the authors seem to have trouble with the idea that
> implementations which don't meet certain common-but-possibly-not-
> universal requirements (e.g. use of two's-complement arithmetic)
> would be unable to support the optional threading features.

Assumes facts not in evidence.

> I'm also not clear what the author of the Standard finds unclear
> about the notion that atomic pointer operations may yield invalid
> pointers but would otherwise have defined behavior;  [...]

Also assumes facts not in evidence.

[toc] | [prev] | [next] | [standalone]


#96408

Fromspacewar@gmail.com
Date2016-11-12 00:48 -0800
Message-ID<a78d7205-33d3-48d1-bf53-a928e042bdcc@googlegroups.com>
In reply to#96383
On Friday, November 11, 2016 at 9:04:38 AM UTC-7, Ben Bacarisse wrote:
> This came up in a DR about the use of various terms relating to atomic
> types and atomic operations:
> 
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_486

> The DR is under review, but I get the feeling the committee agrees that
> the wording is confusing.  I think you can rely on x <op>= y having the
> RMW sematics described in 6.5.16.2 (along with the extensive footnote
> 113).

Thanks!  I'm rather unimpressed with the committee's statement that it "does not feel that this DR is 'actionable'", and that they apparently don't want to address the issues in a Technical Corrigendum. I don't see the outright contradiction between §6.5.16.2 ¶3 and §7.17.7.5 ¶5 as a "small inconsistency".

Oh well.

[toc] | [prev] | [next] | [standalone]


#96409

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-11-12 11:06 +0000
Message-ID<87wpg9lzxr.fsf@bsb.me.uk>
In reply to#96408
spacewar@gmail.com writes:

> On Friday, November 11, 2016 at 9:04:38 AM UTC-7, Ben Bacarisse wrote:
>> This came up in a DR about the use of various terms relating to atomic
>> types and atomic operations:
>> 
>> http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_486
>
>> The DR is under review, but I get the feeling the committee agrees that
>> the wording is confusing.  I think you can rely on x <op>= y having the
>> RMW sematics described in 6.5.16.2 (along with the extensive footnote
>> 113).
>
> Thanks!  I'm rather unimpressed with the committee's statement that it
> "does not feel that this DR is 'actionable'", and that they apparently
> don't want to address the issues in a Technical Corrigendum. I don't
> see the outright contradiction between §6.5.16.2 ¶3 and §7.17.7.5 ¶5
> as a "small inconsistency".

I don't see the wording as an outright contradiction.  The problem comes
down to what atomic means, and the depends on the observer.  x += y is
atomic to an observer in C, but not (I think[1]) to an observer of
volatile accesses.  The functions of 7.17.7.5 are (again, I think)
atomic to all but a hardware observer.

[1] I'm not an expert in this.  I'd welcome a technical discussion of
C's atomic primitives because I either don't understand them properly or
there are other rough edges to the description of them.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#96417

Fromsupercat <flatfinger@casperkitty.com>
Date2016-11-12 11:03 -0800
Message-ID<3468d7af-8959-415f-9da8-e702b0dfe5fd@googlegroups.com>
In reply to#96409
On Saturday, November 12, 2016 at 5:07:03 AM UTC-6, Ben Bacarisse wrote:
> I don't see the wording as an outright contradiction.  The problem comes
> down to what atomic means, and the depends on the observer.  x += y is
> atomic to an observer in C, but not (I think[1]) to an observer of
> volatile accesses.  The functions of 7.17.7.5 are (again, I think)
> atomic to all but a hardware observer.
> 
> [1] I'm not an expert in this.  I'd welcome a technical discussion of
> C's atomic primitives because I either don't understand them properly or
> there are other rough edges to the description of them.

There are a number of places where the Standard defines certain syntactic
forms as equivalent to others, where it would be more helpful to define the
standard-mandated behavioral aspects as being equivalent but explicitly
allow for the operations to differ in other regards not covered by the
Standard.

For example, some hardware platforms include operations to read a value,
write a value, and perform various atomic operations on a value.  On some
platforms, the constructs "atomic += 1;" and "atomic = atomic + 1;" may
have usefully-different meanings, and it would be helpful to have the
Standard specify that when an atomic read-modify-write will have different
effect from an atomic read, computation, and atomic write, compilers may
use syntax to distinguish the two forms.  It might also be helpful to
suggest that compilers include an option to reject the use of compound
operators on atomic values in cases where the operation as a whole cannot
be made atomic, or provide a construct to request an atomic read-modify-
write sequence of a form not supported by any existing operators (e.g.
the Freescale KL27 has hardware so that a single CPU instruction can
trigger atomic operation of the form

   ioreg &= ~mask;
   ioreg |= (value & mask);

in cases where mask is a constant with a single run of 1's in its binary
representation), with the semantics that compilers would not be required
to accept any particular form, but would be required to treat as atomic
any forms they accept.

[toc] | [prev] | [next] | [standalone]


#96501

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-11-13 10:57 -0800
Message-ID<kfny40ntdgq.fsf@x-alumni2.alumni.caltech.edu>
In reply to#96409
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> spacewar@gmail.com writes:
>
>> On Friday, November 11, 2016 at 9:04:38 AM UTC-7, Ben Bacarisse wrote:
>>> This came up in a DR about the use of various terms relating to atomic
>>> types and atomic operations:
>>>
>>> http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_486
>>>
>>> The DR is under review, but I get the feeling the committee agrees that
>>> the wording is confusing.  I think you can rely on x <op>= y having the
>>> RMW sematics described in 6.5.16.2 (along with the extensive footnote
>>> 113).
>>
>> Thanks!  I'm rather unimpressed with the committee's statement that it
>> "does not feel that this DR is 'actionable'", and that they apparently
>> don't want to address the issues in a Technical Corrigendum.  I don't
>> see the outright contradiction between 6.5.16.2 p3 and 7.17.7.5 p5
>> as a "small inconsistency".
>
> I don't see the wording as an outright contradiction.  The problem comes
> down to what atomic means, and the depends on the observer.  x += y is
> atomic to an observer in C, but not (I think[1]) to an observer of
> volatile accesses.  The functions of 7.17.7.5 are (again, I think)
> atomic to all but a hardware observer.
>
> [1] I'm not an expert in this.  I'd welcome a technical discussion of
> C's atomic primitives because I either don't understand them properly or
> there are other rough edges to the description of them.

Note that "atomic operation" is a defined term in the Standard
(in 5.1.2.4 p5).

AFAICT the Standard does not define the term "atomically".  What
I think they mean is that the whole operation is indivisible
as far as other threads are concerned.

The functions in 7.17 are atomic operations (or at least some of
them are - I haven't verified that all are), and they operate
atomically (ditto the last parenthesized comment).

Looking at the extensive footnote, compound assignment operators
do not operate atomically because the combining operation and the
update do not take place indivisibly.  That is, it is possible in
principle for another thread to run "between" the computation of
the new value and the function call that does the update.  The
conditional update and the loop protect against that eventuality
interfering with inter-thread semantics, but even so the operator
is not "indivisible".  And that makes a certain amount of sense,
because most processors probably do not have, eg, an opcode to
do a "read-divide-write" as an indivisible operation.  In the
Standard the term "atomically" looks like it is restricted to
operations that take place "indivisably" from the point of
view of other threads, but a compound assignment operation
might not act that way.

P.S. I don't claim to be an expert either.  I mean just to
offer a contribution to the best of my current understanding.

[toc] | [prev] | [next] | [standalone]


#96500

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-11-13 10:31 -0800
Message-ID<kfn37ivut94.fsf@x-alumni2.alumni.caltech.edu>
In reply to#96408
spacewar@gmail.com writes:

> On Friday, November 11, 2016 at 9:04:38 AM UTC-7, Ben Bacarisse wrote:
>> This came up in a DR about the use of various terms relating to atomic
>> types and atomic operations:
>>
>> http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_486
>>
>> The DR is under review, but I get the feeling the committee agrees that
>> the wording is confusing.  I think you can rely on x <op>= y having the
>> RMW sematics described in 6.5.16.2 (along with the extensive footnote
>> 113).
>
> Thanks!  I'm rather unimpressed with the committee's statement that
> it "does not feel that this DR is 'actionable'", and that they
> apparently don't want to address the issues in a Technical
> Corrigendum.  I don't see the outright contradiction between 6.5.16.2
> p3 and 7.17.7.5 p5 as a "small inconsistency".

I have had a chance now to look into this, mainly reading
carefully new sections of the Standard that have to do with
multi-threading and data races.  First I agree with Ben's
assessment that x <op>= y will behave as you desire.  Second I
believe that what you see as a contradiction is not really a
contradiction, it just looks like one in isolation.  The Standard
is using the term "atomically" in a specialized sense, which is
stronger than just "thread-safe update".  A compound assignment
operator on an atomic type will behave in a way that is thread
safe, as the extensive footnote makes apparent.  However, those
operations are not guaranteed to occur "all in one fell swoop",
which is what "atomically" means in the Standard.  The key piece
of the loop(s) in the footnote /does/ operate atomically;  it is
only the operation as a whole that is not atomic.  The presence
of the loop demonstrates that the behavior is not taking place
"atomically".  However, what you are concerned with it not
whether the operation occurs "atomically" but whether it is
guaranteed to observe appropriate inter-thread semantics.  The
code given in the footnote shows that this property is indeed
respected.

[toc] | [prev] | [next] | [standalone]


#96420

From"Chris M. Thomasson" <invalid@invalid.invalid>
Date2016-11-12 11:24 -0800
Message-ID<o07q85$kbl$1@dont-email.me>
In reply to#96367
On 11/10/2016 7:34 PM, spacewar@gmail.com wrote:
> I'm confused about C11 compound assignments with E1 (left hand side) being an atomic type.
>
> §6.5.16.2 ¶3 states:
>     If E1 has an atomic type, compound assignment is a
>     read-modify-write operation with memory_order_seq_cst memory order
>     semantics.
>
> Footnote 113 says
>     Where a pointer to an atomic object can be formed and E1 and E2 have
>     integer type, this is equivalent to the following code sequence [...]"
> with the code sequence using atomic_compare_exchange_strong().
>
> On the other hand, §7.17.7.5 ¶5 states:
>     NOTE The operation of the atomic_fetch and modify generic functions are
>     nearly equivalent to the operation of the corresponding op= compound
>     assignment operators. The only differences are that the compound
>     assignment operators are not guaranteed to operate atomically, [...]
>
> Doesn't that directly contradict §6.5.16.2 ¶3 and footnote 113?
>
> GCC 6.2.1 generates atomic RMW code for compound assignments with atomic LHS, but the NOTE in §7.17.7.5 makes me worry about that being non-portable.

FWIW, just to be safe, its much better to use the actual atomic 
functions to perform operations on atomic types. They let you 
specifically define exactly what you want, and what type of memory order 
semantics that particular operation requires for your specific program's 
needs.

If you use normal C to, say, increment something like foo = foo + 1 
where foo is an atomic type, the compiler will use strong CAS, and 
memory_order_seq_cst for a mem order. This is just, usually, way to 
strong for most work dealing with atomics.

Just stick to the atomic functions, and remove any possible ambiguities.

[toc] | [prev] | [next] | [standalone]


#96502

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-11-13 10:59 -0800
Message-ID<kfntwbbtdde.fsf@x-alumni2.alumni.caltech.edu>
In reply to#96420
"Chris M. Thomasson" <invalid@invalid.invalid> writes:

> On 11/10/2016 7:34 PM, spacewar@gmail.com wrote:
>> I'm confused about C11 compound assignments with E1 (left hand side)
>>  {} being an atomic type.
>>
>> 6.5.16.2 p3 states:
>>     If E1 has an atomic type, compound assignment is a
>>     read-modify-write operation with memory_order_seq_cst memory order
>>     semantics.
>>
>> Footnote 113 says
>>     Where a pointer to an atomic object can be formed and E1 and E2 have
>>     integer type, this is equivalent to the following code sequence [...]"
>> with the code sequence using atomic_compare_exchange_strong().
>>
>> On the other hand, 7.17.7.5 p5 states:
>>     NOTE The operation of the atomic_fetch and modify generic functions are
>>     nearly equivalent to the operation of the corresponding op= compound
>>     assignment operators.  The only differences are that the compound
>>     assignment operators are not guaranteed to operate atomically, [...]
>>
>> Doesn't that directly contradict 6.5.16.2 p3 and footnote 113?
>>
>> GCC 6.2.1 generates atomic RMW code for compound assignments with
>> atomic LHS, but the NOTE in 7.17.7.5 makes me worry about that being
>> non-portable.
>
> FWIW, just to be safe, its much better to use the actual atomic
> functions to perform operations on atomic types.  They let you
> specifically define exactly what you want, and what type of memory
> order semantics that particular operation requires for your specific
> program's needs.
>
> If you use normal C to, say, increment something like foo = foo + 1
> where foo is an atomic type, the compiler will use strong CAS, and
> memory_order_seq_cst for a mem order.  This is just, usually, way to
> strong for most work dealing with atomics.

That is an interesting statement.  What do you recommend in place
of memory_order_seq_cst, perhaps under various scenarios?

[toc] | [prev] | [next] | [standalone]


#96521

From"Chris M. Thomasson" <invalid@invalid.invalid>
Date2016-11-13 17:34 -0800
Message-ID<o0b49f$2p5$1@dont-email.me>
In reply to#96502
On 11/13/2016 10:59 AM, Tim Rentsch wrote:
> "Chris M. Thomasson" <invalid@invalid.invalid> writes:
>
>> On 11/10/2016 7:34 PM, spacewar@gmail.com wrote:
>>> I'm confused about C11 compound assignments with E1 (left hand side)
>>>  {} being an atomic type.
>>>
>>> 6.5.16.2 p3 states:
>>>     If E1 has an atomic type, compound assignment is a
>>>     read-modify-write operation with memory_order_seq_cst memory order
>>>     semantics.
>>>
>>> Footnote 113 says
>>>     Where a pointer to an atomic object can be formed and E1 and E2 have
>>>     integer type, this is equivalent to the following code sequence [...]"
>>> with the code sequence using atomic_compare_exchange_strong().
>>>
>>> On the other hand, 7.17.7.5 p5 states:
>>>     NOTE The operation of the atomic_fetch and modify generic functions are
>>>     nearly equivalent to the operation of the corresponding op= compound
>>>     assignment operators.  The only differences are that the compound
>>>     assignment operators are not guaranteed to operate atomically, [...]
>>>
>>> Doesn't that directly contradict 6.5.16.2 p3 and footnote 113?
>>>
>>> GCC 6.2.1 generates atomic RMW code for compound assignments with
>>> atomic LHS, but the NOTE in 7.17.7.5 makes me worry about that being
>>> non-portable.
>>
>> FWIW, just to be safe, its much better to use the actual atomic
>> functions to perform operations on atomic types.  They let you
>> specifically define exactly what you want, and what type of memory
>> order semantics that particular operation requires for your specific
>> program's needs.
>>
>> If you use normal C to, say, increment something like foo = foo + 1
>> where foo is an atomic type, the compiler will use strong CAS, and
>> memory_order_seq_cst for a mem order.  This is just, usually, way to
>> strong for most work dealing with atomics.
>
> That is an interesting statement.  What do you recommend in place
> of memory_order_seq_cst, perhaps under various scenarios?
>

Well, if your building a custom lock-free container, perhaps 
memory_order_acquire/release is enough. Or if your building a proxy 
collector, RCU like, a memory_order_consume can be used instead of an 
acquire. It really depends on the algorithms specific needs. 
memory_order_seq_cst is just too strong for a lot of synchronization 
algorithms, and can really destroy performance.

[toc] | [prev] | [next] | [standalone]


#96522

From"Chris M. Thomasson" <invalid@invalid.invalid>
Date2016-11-13 17:48 -0800
Message-ID<o0b549$4o0$1@dont-email.me>
In reply to#96521
On 11/13/2016 5:34 PM, Chris M. Thomasson wrote:
> On 11/13/2016 10:59 AM, Tim Rentsch wrote:
>> "Chris M. Thomasson" <invalid@invalid.invalid> writes:
>>
>>> On 11/10/2016 7:34 PM, spacewar@gmail.com wrote:
>>>> I'm confused about C11 compound assignments with E1 (left hand side)
>>>>  {} being an atomic type.
>>>>
>>>> 6.5.16.2 p3 states:
>>>>     If E1 has an atomic type, compound assignment is a
>>>>     read-modify-write operation with memory_order_seq_cst memory order
>>>>     semantics.
>>>>
>>>> Footnote 113 says
>>>>     Where a pointer to an atomic object can be formed and E1 and E2
>>>> have
>>>>     integer type, this is equivalent to the following code sequence
>>>> [...]"
>>>> with the code sequence using atomic_compare_exchange_strong().
>>>>
>>>> On the other hand, 7.17.7.5 p5 states:
>>>>     NOTE The operation of the atomic_fetch and modify generic
>>>> functions are
>>>>     nearly equivalent to the operation of the corresponding op=
>>>> compound
>>>>     assignment operators.  The only differences are that the compound
>>>>     assignment operators are not guaranteed to operate atomically,
>>>> [...]
>>>>
>>>> Doesn't that directly contradict 6.5.16.2 p3 and footnote 113?
>>>>
>>>> GCC 6.2.1 generates atomic RMW code for compound assignments with
>>>> atomic LHS, but the NOTE in 7.17.7.5 makes me worry about that being
>>>> non-portable.
>>>
>>> FWIW, just to be safe, its much better to use the actual atomic
>>> functions to perform operations on atomic types.  They let you
>>> specifically define exactly what you want, and what type of memory
>>> order semantics that particular operation requires for your specific
>>> program's needs.
>>>
>>> If you use normal C to, say, increment something like foo = foo + 1
>>> where foo is an atomic type, the compiler will use strong CAS, and
>>> memory_order_seq_cst for a mem order.  This is just, usually, way to
>>> strong for most work dealing with atomics.
>>
>> That is an interesting statement.  What do you recommend in place
>> of memory_order_seq_cst, perhaps under various scenarios?
>>
>
> Well, if your building a custom lock-free container, perhaps
> memory_order_acquire/release is enough. Or if your building a proxy
> collector, RCU like, a memory_order_consume can be used instead of an
> acquire.

When one can get away with using memory_order_consume, well, it boils 
down to a nop on a lot of archs out there, except a DEC Alpha!

;^)



> It really depends on the algorithms specific needs.
> memory_order_seq_cst is just too strong for a lot of synchronization
> algorithms, and can really destroy performance.

[toc] | [prev] | [next] | [standalone]


#96624

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-11-15 10:42 -0800
Message-ID<kfnvavoshyr.fsf@x-alumni2.alumni.caltech.edu>
In reply to#96521
"Chris M. Thomasson" <invalid@invalid.invalid> writes:

> On 11/13/2016 10:59 AM, Tim Rentsch wrote:
>> "Chris M. Thomasson" <invalid@invalid.invalid> writes:
>>
>>> On 11/10/2016 7:34 PM, spacewar@gmail.com wrote:
>>>> I'm confused about C11 compound assignments with E1 (left hand side)
>>>>  {} being an atomic type.
>>>>
>>>> 6.5.16.2 p3 states:
>>>>     If E1 has an atomic type, compound assignment is a
>>>>     read-modify-write operation with memory_order_seq_cst memory order
>>>>     semantics.
>>>>
>>>> Footnote 113 says
>>>>     Where a pointer to an atomic object can be formed and E1 and E2 have
>>>>     integer type, this is equivalent to the following code sequence [...]"
>>>> with the code sequence using atomic_compare_exchange_strong().
>>>>
>>>> On the other hand, 7.17.7.5 p5 states:
>>>>     NOTE The operation of the atomic_fetch and modify generic functions are
>>>>     nearly equivalent to the operation of the corresponding op= compound
>>>>     assignment operators.  The only differences are that the compound
>>>>     assignment operators are not guaranteed to operate atomically, [...]
>>>>
>>>> Doesn't that directly contradict 6.5.16.2 p3 and footnote 113?
>>>>
>>>> GCC 6.2.1 generates atomic RMW code for compound assignments with
>>>> atomic LHS, but the NOTE in 7.17.7.5 makes me worry about that being
>>>> non-portable.
>>>
>>> FWIW, just to be safe, its much better to use the actual atomic
>>> functions to perform operations on atomic types.  They let you
>>> specifically define exactly what you want, and what type of memory
>>> order semantics that particular operation requires for your specific
>>> program's needs.
>>>
>>> If you use normal C to, say, increment something like foo = foo + 1
>>> where foo is an atomic type, the compiler will use strong CAS, and
>>> memory_order_seq_cst for a mem order.  This is just, usually, way to
>>> strong for most work dealing with atomics.
>>
>> That is an interesting statement.  What do you recommend in place
>> of memory_order_seq_cst, perhaps under various scenarios?
>
> Well, if your building a custom lock-free container, perhaps
> memory_order_acquire/release is enough.  Or if your building a proxy
> collector, RCU like, a memory_order_consume can be used instead of an
> acquire.  It really depends on the algorithms specific
> needs.  memory_order_seq_cst is just too strong for a lot of
> synchronization algorithms, and can really destroy performance.

I see.  IIUC, what you're saying is that using memory_order_seq_cst
all the time is too expensive, so in most cases more specialized
patterns are used that can employ less expensive sequencing
guarantees.  Did I understand that right or is there something
more?

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web