Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is increment an integer atomic in x86? [duplicate]

Tags:

c++

c

x86

gcc

x86-64

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?

like image 241
pythonic Avatar asked May 08 '12 17:05

pythonic


People also ask

Is ++ an operation atomic?

On objects without an atomic type, standard never defines ++ as an atomic operation.

Is ++ in C Atomic?

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.

Are X86 instructions Atomic?

x86 guarantees that aligned loads and stores up to 64 bits are atomic, but not wider accesses.

What is atomically increment?

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.


1 Answers

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.

like image 172
Ira Baxter Avatar answered Sep 21 '22 15:09

Ira Baxter