Reputation: 6052
I'm wondering if I need to use std::atomic
in the following case:
if I'm only looking for the following type of consistency:
If yes, which memory order should I use in load/store (out of memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst
) to get as little overhead as possible?
As an example, suppose I want to implement a "static" singly-linked list which can only insert at tail and never delete or change any of the next pointers, i.e.:
Entry {
...
const Entry* next; // or std::atomic<const Entry*> next;
Entry() : next(NULL) { ... }
...
};
void Insert(Entry* tail, const Entry* e) {
tail->next = e; // assuming tail != NULL (i.e. we always have a dummy node)
}
Upvotes: 2
Views: 353
Reputation: 300
To decide what memory ordering you need, you need to provide more information about what you will use the member variable for. If you are using a atomic pointer field to reference a newly created object and that the object has fields you want to the readers to access, then you need to make sure synchronization is established. That means that store needs to be a release, and the loads probably should be acquires. Though depending on the details consume might work. At this point, there isn't really any advantage of using consume performance wise so I'd probably stick to acquire.
Try playing around with examples using CDSChecker to get an idea of what you need to do.
Upvotes: 0
Reputation: 34608
Memory order only dictates which writes or reads to other variables than the atomic one are being seen by other threads. If you don't care about the other writes or reads in your thread in relation to your member variable, you can even use std::memory_order_relaxed
.
To question how fast other threads see writes on your atomic variable, the standard says the following: (§ 29.3.13)
Implementations should make atomic stores visible to atomic loads within a reasonable amount of time.
Upvotes: 1