On a multicore x86 machine, Say a thread executing on core1 increments an integer variable a
at the same time thread on core 2 also increments it. Given that the initial value of a
was 0, would it always be 2
in the end? Or it could have some other value? Assume that a
is declared as volatile
and we are not using atomic variables (such as atomic<> of C++ and built in atomic operations in gcc).
If the value of a
would indeed be always 2 in such event, does that mean that a long int
in x86-64 would also have the same property, that is, a
will always be 2 in the end?
On objects without an atomic type, standard never defines ++ as an atomic operation.
The C / C++ language itself makes no claim of atomicity or lack thereof. You need to rely on intrinsics or library functions to ensure atomic behavior.
x86 guarantees that aligned loads and stores up to 64 bits are atomic, but not wider accesses.
In computer science, the fetch-and-add CPU instruction (FAA) atomically increments the contents of a memory location by a specified value. That is, fetch-and-add performs the operation increment the value at address x by a, where x is a memory location and a is some value, and return the original value at x.
The increment-memory machine instruction on an X86 is atomic only if you use it with a LOCK prefix.
x++ in C and C++ doesn't have atomic behavior. If you do unlocked increments, due to races in which processor is reading and writing X, if two separate processors attempt an increment, you can end up with just one increment or both being seen (the second processor may have read the initial value, incremented it, and written it back after the first writes its results back).
I believe that C++11 offers atomic increments, and most vendor compilers have an idiomatic way to cause an atomic increment of certain built-in integer types (typically int and long); see your compiler reference manual.
If you want to increment a "large value" (say, a multiprecision integer), you need to do so with using some standard locking mechanism such as a semaphore.
Note that you need to worry about atomic reads, too. On the x86, reading a 32 or 64 bit value happens to be atomic if it is 64-bit word aligned. That won't be true of a "large value"; again you'll need some standard lock.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With