Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenMP atomic: Difference between write and update

Tags:

c

atomic

openmp

I am reading the OMP documentation (6.0) about atomic operations. As I came across clauses I read about write and update. I understand the difference between the two:

  • write is used to atomically write to a variable
  • update is used to atomically read the variable and give it a new value with write

I wanted to test it out. I thought that write should fail when trying to read and write, but it wasn't the case. Can anyone explain to me, why the code bellow always gives the same result?

#include <stdio.h>
#include <omp.h>

int main() {
    int sum = 0;

    #pragma omp parallel for num_threads(64)
    for (int i = 1; i <= 100000000; i++) {
        #pragma omp atomic write
        sum = sum + 1;
    }

    printf("Sum with write: %d\n", sum);
    return 0;
}

My understanding was that the reads would not be thread safe and result would be inconsistent, but I got the same correct result each time:

like image 459
GabrijelOkorn Avatar asked Jan 19 '26 03:01

GabrijelOkorn


1 Answers

The difference between atomic update and atomic write is the "atomic domain" or what is actually done atomically.

When using atomic write, only the left-hand side assignment is performed atomically. The sum+1 part is not done atomically. The right-hand side of the statement is executed non-atomically and therefore maybe subject to race conditions when one thread as (atomically) updated sum while another thread as just read a value and increments it, not seeing the update from the other thread. Think it as being something like:

tmp = sum + 1 // done non-atomically
sum = tmp     // via atomic store operation 

With atomic update the whole operation of sum = sum + 1 is performed atomically. So, it's both the RHS and LHS inkl. the addition operation that is performed in one unbreakable step. Note that, as per, OpenMP specification if it is sum = sum + expr with expression being something complex such as a function call, the evaluation is not part of the atomic domain:

tmp = 1          // non-atomically evaluate expr (here expr is just 1)
sum = sum + tmp; // done with atomic add instruction
like image 153
Michael Klemm Avatar answered Jan 20 '26 17:01

Michael Klemm