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:
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:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With