Saturday, October 1, 2022

[FIXED] How can an atomic operation be not a synchronization operation?

Issue

The standard says that a relaxed atomic operation is not a synchronization operation. But what's atomic about an operation result of which is not seen by other threads.

The example here wouldn't give the expected result then, right?

What I understand by synchronization is that the result of an operation with such trait would be visible by all threads.

Maybe I don't understand what synchronization means. Where's the hole in my logic?


Solution

The compiler and the CPU are allowed to reorder memory accesses. It's the as-if rule and it assumes a single-threaded process.

In multithreaded programs, the memory order parameter specifies how memory accesses are to be ordered around an atomic operation. This is the synchronization aspect (the "acquire-release semantics") of an atomic operation that is separate from the atomicity aspect itself:

int x = 1;
std::atomic<int> y = 1;

    // Thread 1
    x++;
    y.fetch_add(1, std::memory_order_release);

    // Thread 2
    while ((y.load(std::memory_order_acquire) == 1)
    { /* wait */ }
    std::cout << x << std::endl;  // x is 2 now

Whereas with a relaxed memory order we only get atomicity, but not ordering:

int x = 1;
std::atomic<int> y = 1;

    // Thread 1
    x++;
    y.fetch_add(1, std::memory_order_relaxed);

    // Thread 2
    while ((y.load(std::memory_order_relaxed) == 1)
    { /* wait */ }
    std::cout << x << std::endl;  // x can be 1 or 2, we don't know

Indeed as Herb Sutter explains in his excellent atomic<> weapons talk, memory_order_relaxed makes a multithreaded program very difficult to reason about and should be used in very specific cases only, when there is no dependency between the atomic operation and any other operation before or after it in any thread (very rarely the case).



Answered By - rustyx
Answer Checked By - Timothy Miller (PHPFixing Admin)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.