Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Atomic behavior of unary increment operators

Somewhere I read that unary operators are atomic by nature and so they can be used as it is in multi threaded environment. To confirm the same, I wrote two separate programs where in

  1. I used a variable x and incremented using unary operator ++x
  2. I used a variable x and incremented using x=x+1

I compared the disassembly of both programs and found no difference. Please provide your inputs on this.

like image 977
user3505805 Avatar asked Dec 18 '18 11:12

user3505805


People also ask

Is ++ an atomic operation?

h. If you have an object with an atomic type, a postfix and prefix operators ++ will define an atomic operation as: read-modify-write operation with memory_order_seq_cst memory order semantics. You can also use atomic_fetch_add() if you want an atomic increment.

Is increment operator Atomic?

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.

Is operator ++ atomic in C++?

std::atomic::operator++The entire operation is atomic: the value cannot be modified between the instant its value is read and the moment it is modified by this function. This function behaves as if atomic::fetch_add was called with 1 and memory_order_seq_cst as arguments.

Is increment Atomic C?

@ Steve: No, in C, increment is not atomic. If you need an atomic operation, use your platform's corresponding API. Relying on implementation-defined behaviour (which might change with compiler options or version without further notice) is the road to pain.


1 Answers

When writing cross platform C++, you only have atomic behavior when using std::atomic<>.

It is true that on certain platforms, like Intel 64bit, the processor guarantees that inc is atomic. However, please don't write code that depends on this! As your future debugger, I would like to know which data is intended to be shared over threads and which isn't.

Using std::atomic<int> might be a bit more work to write, however, it does guarantee that everything behaves atomically (on every platform) by either falling back to the platform requirements (std::atomic::is_lock_free), or by explicitly putting a lock around the access. It as well insert guards in order to make sure that the caches of the other processor cores are invalidated (if the platform requires this).

In practice for Intel 64bit, this should give you the same assembly, if not, log a bug on your compiler.

At the same time, some operations with ints might not be atomic (operator*=), std::atomic simply doesn't hold those operations, requiring you to correctly work with those.

On a side note: ++x and x = x+1 are different operations, they might be optimized to the same assembly. Given non-atomic platform requirements, the second suddenly is a bug which takes days to solve.

like image 138
JVApen Avatar answered Oct 08 '22 11:10

JVApen