Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the difference between ++, add operation and fetch_add() in atomic()

Tags:

I ran following code many times but why the result for prefix increment , fetch_add() shows the correct result while with add operation (+), it prints the wrong result?

#include <iostream> #include <mutex> #include <future> using namespace std; atomic <int> cnt (0); void fun() {     for(int i =0; i <10000000 ; ++i)     {        //++cnt; // print the correct result 20000000         //cnt = cnt+1; // print wrong result, arbitrary numbers         cnt.fetch_add(1); //  print the correct result 20000000      } } int main() {     auto fut1 = async(std::launch::async, fun);     auto fut2 = async(std::launch::async, fun);     fut1.get();     fut2.get();     cout << "value of cnt: "<<cnt <<endl;  }  
like image 445
Alok Avatar asked Aug 29 '18 05:08

Alok


People also ask

What is Fetch_add Atomic?

atomic::fetch_add (C++11)Atomically adds a value to an existing value that is stored in an atomic object. Memory is affected according to the value of order .

Is += an atomic operation?

For the change in value to be visible across cores, a += (for instance) would have to load the value, add the increment and then store it. This means that the operation will not be atomic.

What is atomic operation in operating system?

Atomic operations are sequences of instructions that guarantee atomic accesses and updates of shared single word variables. This means that atomic operations cannot protect accesses to complex data structures in the way that locks can, but they provide a very efficient way of serializing access to a single word.

What are atomic operations in C++?

(C++11) [edit] The atomic library provides components for fine-grained atomic operations allowing for lockless concurrent programming. Each atomic operation is indivisible with regards to any other atomic operation that involves the same object. Atomic objects are free of data races.


1 Answers

++cnt and cnt.fetch_add(1) are truly atomic operations. One thread is blocked while the other thread reads, increments, and updates the value. As such, the two threads cannot step on each other's toes. Access to cnt is fully serialized, and the final result is as you would expect.

cnt = cnt+1; is not fully atomic. It involves three separate operations, only two of which are atomic, but one is not. By the time a thread has atomically read the current value of cnt and made a copy of it locally, the other thread is no longer blocked and can freely modify cnt at will while that copy is being incremented. Then, the assignment of the incremented copy back to cnt is done atomically, but will be assigning a stale value if cnt has already been modified by the other thread. So the final result is random and not what you would expect.

like image 78
Remy Lebeau Avatar answered Oct 09 '22 00:10

Remy Lebeau