What is atomic?
Atomic, as describing something with the property of an atom. The word atom originates from Latin atomus meaning "undivided".
Typically I think of an atomic operation (regardless of language) to have two qualities:
An atomic operation is always undivided.
I.e. it is performed in an indivisible way, I believe this is what OP refers to as "threadsafe". In a sense the operation happens instantaneously when viewed by another thread.
For example the following operation is likely divided (compiler/hardware dependent):
i += 1;
because it can be observed by another thread (on hypothetical hardware and compiler) as:
load r1, i;
addi r1, #1;
store i, r1;
Two threads doing the above operation i += 1
without appropriate synchronization may produce the wrong result. Say i=0
initially, thread T1
loads T1.r1 = 0
, and the thread T2
loads t2.r1 = 0
. Both threads increment their respective r1
s by 1 and then store the result to i
. Although two increments have been performed, the value of i
is still only 1 because the increment operation was divisible. Note that had there been synchronization before and after i+=1
the other thread would have waited until the operation was complete and thus would have observed an undivided operation.
Note that even a simple write may or may not be undivided:
i = 3;
store i, #3;
depending on the compiler and hardware. For example if the address of i
is not aligned suitably, then an unaligned load/store has to be used which is executed by the CPU as several smaller loads/stores.
An atomic operation has guaranteed memory ordering semantics.
Non atomic operations may be re-ordered and may not necessarily occur in the order written in the program source code.
For example, under the "as-if" rule the compiler is allowed to re-order stores and loads as it sees fit as long as all access to volatile memory occurs in the order specified by the program "as if" the program was evaluated according to the wording in the standard. Thus non-atomic operations may be re-arranged breaking any assumptions about execution order in a multi-threaded program. This is why a seemingly innocent use of a raw int
as a signaling variable in multi-threaded programming is broken, even if writes and reads may be indivisible, the ordering may break the program depending on the compiler. An atomic operation enforces ordering of the operations around it depending on what memory semantics are specified. See std::memory_order
.
The CPU may also re-order your memory accesses under the memory ordering constraints of that CPU. You can find the memory ordering constraints for the x86 architecture in the Intel 64 and IA32 Architectures Software Developer Manual section 8.2 starting at page 2212.
Primitive types (int
, char
etc) are not Atomic
Because even if they under certain conditions may have indivisible store and load instructions or possibly even some arithmetic instructions, they do not guarantee the ordering of stores and loads. As such they are unsafe to use in multi-threaded contexts without proper synchronization to guarantee that the memory state observed by other threads is what you think it is at that point in time.
I hope this explains why primitive types are not atomic.
std::atomic
: ordering with respect to other loads/stores? Either way, the C++ standard doesn't provide either guarantee, not even for achar
AFAIK. On most hardware, the first (std::atomic<T>::store(val, std::memory_order_relaxed)
) is free up to the size of a register (but that still doesn't make a read-modify-write++i
free if you want the whole RMW to be atomic). – Christanx = 0xaaaaaaaaaaaaaaaa
compiles to two stores of0xaaaaaaaa
. But constants where the two halves are different do happen to get stored with a single 64-bitstr
w. GCC, See also lwn.net/Articles/793253 – Christanmemory_order_relaxed
forstd::atomic
? – Christanwhile(!ready) {}
intoif(!ready) while(42){}
. MCU programming - C++ O2 optimization breaks while loop. You only asked about tearing, not stopping the compiler from optimizing variables into registers (let alone memory ordering wrt. other operations), so I didn't mention this earlier. – Christan