-7

Is it safe to assume read/write of double value is atomic in a 64-bit machine with c/c++ programming

I have two process sharing a memory. process 1 is in c, which is the writer of double value and process 2 in c++ is reader of this value.

user1762571
  • 1,888
  • 7
  • 28
  • 47
  • Do you mean written as one atomic item, visible to other threads, or both? – Richard Critten Apr 24 '18 at 16:13
  • I think he asks if a double in c is stored the same way as in c++ memory-wise – posixpascal Apr 24 '18 at 16:25
  • What do you mean by "process", and how are they "sharing a memory"? –  Apr 24 '18 at 16:28
  • Please search for answers, because this issue is addressed in many questions on StackOverflow. If you have looked at various posts and yours is different, cite which ones you looked at and why they don't apply or what's special about your case. For example, see [Naturally aligned atomicity](https://stackoverflow.com/questions/36624881/why-is-integer-assignment-on-a-naturally-aligned-variable-atomic-on-x86/36685056#36685056). You'll see that there are a number of factors involved. – Jeff Learman Apr 24 '18 at 17:35
  • C++11 std::atomic in shared memory between 2 processes works if they're lock-free, otherwise they won't share a hash table of locks. `std::atomic` is lock-free on the mainstream x86-64 compilers. – Peter Cordes Apr 25 '18 at 09:30
  • 1
    @JeffLearman: I saw you linked my answer on x86 atomic stores :) I'd actually already written one about `atomic` too, so we can close this as a dup :P – Peter Cordes Apr 25 '18 at 09:31

2 Answers2

3

No, if you want atomic operations use std::atomic<double>

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • I have two process sharing a memory. process 1 is in c, which is the writer of double value and process 2 in c++ is reader of this value. what should i do in this case? – user1762571 Apr 24 '18 at 16:16
  • 1
    This answer is correct from pure language perspective, but the target machine is x86-64, which does support aligned 2/4/8-byte atomic memory operations. Compilers also offer certain alignment guarantees. – Hadi Brais Apr 24 '18 at 16:27
  • Ok, that's a completely different question, the answer is probably yes if your standard library's implementation of `std::atomic` is lock free, see http://en.cppreference.com/w/cpp/atomic/atomic/is_lock_free – Alan Birtles Apr 24 '18 at 16:28
  • @HadiBrais this answer was to the original question which was much less specific – Alan Birtles Apr 24 '18 at 16:30
  • 1
    The original question was about not only C++, but also C which will not have the STL. – Christian Gibbons Apr 24 '18 at 16:34
  • 1
    Shared memory between processes: you will need to use Operating System synchronisation primitives to get cache coherency. Standard C++ (only): has nothing to help you with multi-process, we have only just got thread support. The change/clarification to the question makes this answer incorrect. – Richard Critten Apr 24 '18 at 16:49
  • @RichardCritten: on at least the mainstream x86 C++ implementations on mainstream OSes (Linux, OS X, Windows), `std::atomic` is lock-free and is atomic between processes on a normal machine, even a multi-socket machine. Shared memory between processes is cache coherent on all normal systems, including all x86-64. – Peter Cordes Apr 25 '18 at 09:25
  • @PeterCordes including Arm? I was referencing to the fact that the C++ standard does not not (yet) admit that we can have concurrent processes so any answer that references the standard needs an addendum. – Richard Critten Apr 25 '18 at 09:43
  • @RichardCritten: This is explicitly an x86-64 question, but yes AArch64 has lock-free `atomic`, and so does ARM32 with `gcc -mcpu=cortex-a57` [example on Godbolt](https://godbolt.org/g/NHo76t). The C++11 standard does explicitly recommend that atomics should be address-free when they're lock-free, and thus work in shared-memory between processes (using those terms), on implementations where those terms are meaningful. [ISO C++ 32.5 point 4](http://eel.is/c++draft/atomics.lockfree). Being address-free is totally normal for lock-free atomics; it would be weird to store your own addr. – Peter Cordes Apr 25 '18 at 10:02
  • @RichardCritten: Just noticed ARM32 uses [a LL/SC retry loop](https://en.wikipedia.org/wiki/Load-link/store-conditional) for double-word atomic store, but relaxed double-word atomic load can get away with just `ldrd` on Cortex-A15, which is just a normal 2-register store, not LL/SC https://godbolt.org/g/Zv1un8. (or `ldrexd` on Cortex-A9). Seems weird that double-word loads are "naturally" atomic but double-word stores aren't. That is a possible microarchitecture design choice, though. – Peter Cordes Apr 25 '18 at 10:48
  • @RichardCritten: Cache coherency is an important related topic, but it is actually independent of atomicity. Instead, it affects apparent order of operations. Furthermore, if only one process writes and only one process reads, temporary lack of coherency would simply delay updates. But please let us know if cache incoherency could persist if synchronization primitives aren't used. – Jeff Learman Apr 25 '18 at 15:59
0

C11 introduced atomic types: C11 Atomics

With any luck, C++ also adopted these for portability. If not, you may have to rely on compiler extensions: GCC Atomic Builtins

Or simply locking with a mutex.

Christian Gibbons
  • 4,272
  • 1
  • 16
  • 29
  • I think it was the other way around; C++11 `std::atomic` was designed first, then C11 basically copied the design, keeping the memory model the same. (It's not necessarily guaranteed that C11 `_Atomic int` and C++11 `std::atomic` are binary compatible, though, if linking C and C++ together. They probably are on most platforms, especially for `int`.) – Peter Cordes Apr 25 '18 at 09:19