This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
On 11/14/2016 4:34 PM, Bin Fan wrote:
Hi All,I have an updated version of libatomic ABI specification draft. Please take a look to see if it matches GCC implementation. The purpose of this document is to establish an official GCC libatomic ABI, and allow compatible compiler and runtime implementations on the affected platforms.Compared to the last version you have reviewed, here are the major updates- Rewrite the notes in N2.3.2 to explicit mention the implementation of __atomic_compare_exchange follows memcmp/memcpy semantics, and the consequence of it.- Rewrite section 3 to replace "lock-free" operations with "hardware backed" instructions. The digest of this section is: 1) inlineable atomics must be implemented with the hardware backed atomic instructions. 2) for non-inlineable atomics, the compiler must generate a runtime call, and the runtime support function is free to use any implementation.- The Rationale section in section 3 is also revised to remove the mentioning of "lock-free", but there is not major change of concept.- Add note N3.1 to emphasize the assumption of general hardware supported atomic instruction- Add note N3.2 to discuss the issues of cmpxchg16b- Add a paragraph in section 4.1 to specify memory_order_consume must be implemented through memory_order_acquire. Section 4.2 emphasizes it again.- The specification of each runtime functions mostly maps to the corresponding generic functions in the C11 standard. Two functions are worth noting: 1) C11 atomic_compare_exchange compares and updates the "value" while __atomic_compare_exchange functions in this ABI compare and update the "memory", which implies the memcmp and memcpy semantics. 2) The specification of __atomic_is_lock_free allows both a per-object result and a per-type result. A per-type implementation could pass NULL, or a faked address as the address of the object. A per-object implementation could pass the actual address of the object.Thanks, - Bin On 8/10/2016 3:33 PM, Bin Fan wrote:Hi Torvald, Thanks a lot for your review. Please find my response inline... On 8/5/2016 8:51 AM, Torvald Riegel wrote:This paragraph is just to clarify that _Atomic does not change (e.g. zeroing out) the padding bits, whose content were undefined in the current SPARC and x86 ABI specifications, and will[CC'ing Andrew MacLeod, who has been working on the atomics too.] On Tue, 2016-08-02 at 16:28 -0700, Bin Fan wrote:I'm wondering if you have a chance to review the revised libatomic ABI draft. The email was rejected by the gcc alias once due to some htmlstuff in the email text. Though I resend a pure txt format version, I'mnot sure if it worked, so this time I drop the gcc alias.If you do not have any issues, I'm wondering if this ABI draft could bepublished in some GCC wiki or documentation? I'd be happy to prepare a version without the "notes" part.Because the padding of structure types is not affected by _Atomic modifier, the contents of any padding in the atomic structure objectis still undefined, therefore the atomic compare and exchange operationon such objects may fail due to the difference of the padding.I think this isn't quite clear.still be undefined for _Atomic aggregates.This paragraph is part of "notes" rather than the main body of the ABI draft. If it is not clear,I will change it by mentioning the memcmp/memcpy-like semantics.Perhaps it's easier to describe it in the way that C++ does, referring to the memcmp/memcpy-like semantics of compare_exchange (e.g., see N4606 29.6.5p27). C11 isn't quite clear about this, or I am misunderstanding what they really mean by "value of the object" (see N1570 7.17.7.4p2).This is the subject of C11 Defect Report 431: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2059.htm#dr_431 which has been fixed to align with the C++ standard and closed with a Proposed Technical Corrigendum which will appear in the next revision of the C standard (~2017). Note that in section 4.2 of this ABI draft, the function description of__atomic_compare_exchange uses "compares the memory pointed to by object" instead of "compares the value pointed to by object" as you quoted from N1570 7.17.7.4p.Since you asked about whether you should review the function descriptions, this is one of the two worth noticing cases. I will mention another one later in this email.I agree that lock-free atomic operations does not equivalent to HW-backed atomic operations. I will think about how to mention it in the ABI. My current thought is asLock-free atomic operations does not require runtime support functions.I think it's better to say that the support functions must be compatibleThe compiler may generate inlined code for efficiency. This ABI specification defines a few inlineable atomic types. An atomic type is inlineable means the compiler may generate inlined instruction sequence for atomic operations on such types. The implementation of the support functions for the inlineable atomic types must also be lock free.with what the compiler would generate. That they are "lock-free" isjust a forward progress property. This also applies to later paragraphs in the draft. Maybe we need to use a different term here, so we can useit for what we want (ie, a HW-backed, inlineable operation).you suggested, to change "lock-free" to "HW-backed". So an example of the updated specification would be like this:The implementation of the support functions for the inlineable atomic types must use HW-backed atomic instructions. For atomic operations on not inlineable types, the compilermust always generate support function calls.At least GCC 6.1.0 still generates cmpxchg16b for an atomic load with -march=nativeOn all affected platforms, atomic types whose size equal to 1, 2, 4 or 8 and alignment matches the size are inlineable On the 64-bit x86 platform which supports the cmpxchg16b instruction, 16-byte atomic types whose alignment matches the size is inlineable.I still think making 16-byte atomic types inlined / lock-free when all we have is a wide cmpxchg is wrong. AFAIK there is no atomic 16-byte load instruction on x86 (or is there?), even though cmpxchg16b might be available.on my haswell machine.If the 16-byte atomic read is implemented in software, the current implementation still uses a lock/mutex, meaning a write will happen somewhere, maybe not directly on the object memory but on somewhere else(a spinlock or a mutex). It can resolve the read-only issue you mentioned, because the write is on the lock rather than on theI'd prefer if we could fix this in GCC in some way instead of requiring this by putting it into the ABI. This also applies to the double-wide CAS on i386. IIRC, there is a BZ about this somewhere, but I don't find it. Andrew, do you remember? Basically, there is a correctness and a performance problem. The atomic variable might be in a read-only-mapped page, which isn'tunreasonable given that the C/C++ standards explicitly require lock-freeatomics to be address-free too, which is a clear hint towards enabling mapping memory to more than one place in the address space. So, if the user does an atomic load on a 16-byte variable accessible through a read-only page, we'll get a segfault. One could argue that C/C++ don't provide any mmap feature, and thus you can't expect this to work. But this doesn't seem a good argument to make from a user's perspective.Second, I'd argue that the "lock-free" property is used by most users asan indication of which atomics might be as fast as one would expect typical HW to be -- not because they are interested in the forward progress aspect or the address-free aspect. If atomic loads do cause writes, the performance of a load will be horrible because of the contention in cases where many threads issue loads.object, But there would still be the performance issue of contention. There are some advanced software algorithms that can make thismost-reader-occational-writer scenario more efficient. (For example, seqlock mentionedin here: http://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf)The performance of such algorithms would depend highly on the use cases, so maybe the user should implement their own algorithm instead of relying on the compiler/libatomiclibrary to provide the best performance in all cases.I'm OK with the current GCC implementation, which I believe matches the ABI draft. AndThis is even more unfortunate considering that if one has a 64b CAS, then one canincrement a 64b counter which can be considered to never overflow, whichallows one to build efficient atomic snapshots of larger atomic variables. OTOH, some people would like to use the GCC builtins to get access to cmpxchg16b. Irrespective of how we deal with this, we should at least document the current state and the problems associated with it. Maybe we should consider providing separate builtins for cmpxchg16b.we can document the current issues as appendix or whatever.If GCC is willing to change, I'm also OK with specifying that 16-byte atomic types arenot inlineable.Right. The ABI specification itself is ISA-specific. For example, if we call it SPARC V9 ABI amendment, then it is safe to assume that the ISA support 1,2,4,8 -byte atomic hardware instructions, then it is safe to make such specification of "inlineable" in the ABI."Inlineability" is a compile time property, which in most cases dependsonly on the type. In a few cases it also depends on whether the target ISA supports the cmpxchg16b instruction. A compiler may get the ISA information by either compilation flags or inquiring the hardwarecapabilities. When the hardware capabilities information is not available, the compiler should assume the cmpxchg16b instruction is not supported.I think that strictly speaking, it always depends on the target ISA, because we assume that it provides 1-byte atomic operations, for example.I'm not very familiar with x86 ISA versioning. I used to assume cmpxchg16b is available on all today's mainstream x86 platforms until I found Xeon Phi does not support it. That'swhy the ABI says it depends on target ISA.As far as I can tell, neither SPARC or x86 has instructions that may benefit from the consumememory_order_consume = 1,[...]Refer to C standard for the meaning of each enumeration constants of memory_order type.[...]Most of the functions listed in this section can be mapped to the genericfunctions with the same semantics in the C standard. Refer to the Cstandard for the description of the generic functions and how each memoryorder works.We need to say that memory_order_consume must be implemented through memory_order_acquire. The compiler can't preserve dependencies correctly and will never be able to for the current specification of consume. Thus, we must fall back to acquire MO.order. So I'm happy to make this change.In the above I mentioned there may be two places in the descriptions that may be interesting. I have mentioned one in the above (__atomic_compare_exchange). The other one isI haven't looked at the descriptions of the individual atomic operationsin detail. Let me know if I should.__atomic_is_lock_free. This is based on Richard's comments.Thanks again for your review, I will send a new draft based on your comments. Please send meany further comments/suggestions. Thanks, - BinTorvald
Attachment:
libatomicABIdraft.txt
Description: Text document
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |