The C++ memory model has relaxed atomics, which do not put any ordering guarantees on memory operations. Other than the mailbox example in C which I have found here:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1525.htm
Based on the motivating example in this paper:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2153.pdf
I was curious about other use cases for this type of synchronization mechanism.
A simple example that I see in my work frequently is a stats counter. If you
want to count the number of times an event happens but don't need any sort of
synchronization across threads aside from making the increment safe, using
memory_order_relaxed
makes sense.
static std::atomic<size_t> g_event_count_;
void HandleEvent() {
// Increment the global count. This operation is safe and correct even
// if there are other threads concurrently running HandleEvent or
// PrintStats.
g_event_count_.fetch_add(1, std::memory_order_relaxed);
[...]
}
void PrintStats() {
// Snapshot the "current" value of the counter. "Current" is in scare
// quotes because the value may change while this function is running.
// But unlike a plain old size_t, reading from std::atomic<size_t> is
// safe.
const size_t event_count =
g_event_count_.load(std::memory_order_relaxed);
// Use event_count in a report.
[...]
}
In both cases, there is no need to use a stronger memory order. On some platforms, doing so could have negative performance impact.
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