Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do atomic operations like fetch-and-add return the old value of the variable being changed?

I am trying to learn and get better at understanding multithreading, but I got hung up on the behavior of atomic functions like fetch-and-add. In the specific case of fetch-and-add, it is my understanding that a value (let's say x which currently equals 5) is added to by an increment value (let's say 3), the resulting sum (8) is written to x's place in memory, yet the old value (5) is returned.

There are several other such functions in different places (like OpenGL's atomic functions, Java's AtomicIntegers, and many more areas) that behave like this. But what I don't understand is why a place in code would want to write to memory and yet still return the value that it wanted to modify in the first place. Can anyone help shed light on this?

like image 763
hashahid Avatar asked Apr 07 '16 18:04

hashahid


People also ask

How do atomic operations work?

During an atomic operation, a processor can read and write a location during the same data transmission. In this way, another input/output mechanism or processor cannot perform memory reading or writing tasks until the atomic operation has finished.

What is an atomic operation example?

An example of atomic operation is instruction execution, usually an instruction feed to the execution unit can't be stopped in the middle. Yet, a statement in high level language results in multiple instructions. It is the root cause of non-atomic operations.

Is reading in an atomic operation?

In computer science, read–modify–write is a class of atomic operations (such as test-and-set, fetch-and-add, and compare-and-swap) that both read a memory location and write a new value into it simultaneously, either with a completely new value or some function of the previous value.

Is increment an atomic operation?

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.


2 Answers

The answer is very simple. The nature of atomic functions is that they modify (increment in this case) the actual value at the time of execution which might be different from the value as your code knew it.

example:

x = 5; // x is global
y = atomically_increment(x);
// what is y? 

Now, if x happened to be changed from 5 to 6 right before increment actually took place, y would be equal to 6, and x to 9.

like image 98
SergeyA Avatar answered Oct 19 '22 00:10

SergeyA


To expand on Sergey's answer...

I look at fetch-and-add to be something similar to a semaphore; except the fetch-and-add call makes everything an atomic operation. Here is an example of an algorithm that shows the use of the original value: http://research.omicsgroup.org/index.php/Ticket_lock

like image 2
Carlos Avatar answered Oct 19 '22 00:10

Carlos