jaeyong
jaeyong

Reputation: 9363

What is the use-case of atomic read

I understand that atomic read serializes the read operations that performed by multiple threads.

What I don't understand is what is the use case?

More interestingly, I've found some implementation of atomic read which is

static inline int32_t ASMAtomicRead32(volatile int32_t *pi32)
{
    return *pi32;
}

Where the only distinction to regular read is volatile. Does it mean that atomic read is the same as volatile read?

Upvotes: 3

Views: 224

Answers (1)

Anton
Anton

Reputation: 6577

I understand that atomic read serializes the read operations that performed by multiple threads.

It's rather wrong. How you can ensure the order of reads if there is no write which stores a different value? Even when you have both read and write, it's not necessarily serialized unless correct memory semantics is used in conjunction with both the read & write operations, e.g. 'store-with-release' and 'load-with-acquire'. In your particular example, the memory semantics is relaxed. Though on x86, one can imply acquire semantics for each load and release for each store (unless non-temporal stores are used).

What I don't understand is what is the use case?

atomic reads must ensure that the data is read in one shot and no other thread can store a part of the data in the between. Thus it usually ensures the alignment of the atomic variable (since the read of aligned machine word is atomic) or work-arounds non-aligned cases using more heavy instructions. And finally, it ensures that the read is not optimized out by the compiler nor reordered across other operations in this thread (according to the memory semantics).

Does it mean that atomic read is the same as volatile read?

In a few words, volatile was not intended for such a use-case but sometimes can be abused for it when other requirements are met as well. For your example, my analysis is the following:

  1. int32_t is likely a machine word or less - ok.
  2. usually, everything is aligned at least on 4 bytes boundary, though there is no guarantee in your example
  3. volatile ensures the read is not optimized out
  4. the is no guarantee it will not be reordered either by processor (ok for x86) or by compiler (bad)

Please refer to Arch's blog and Concurrency: Atomic and volatile in C++11 memory model for the details.

Upvotes: 2

Related Questions