简体   繁体   中英

Non-atomic access to atomic through a union

I would like to manipulate the same memory location both atomically and non-atomically.

Let's suppose that I'm working with a simple type, like an int , and in particular that std::atomic<T>::is_lock_free() returns true , and that sizeof(T) == sizeof(std::atomic<T>) .

I thought that a reinterpret_cast should work:

std::atomic<int> x;
int& xx = reinterpret_cast<int&>(x);

But N4013 explains that this may confuse type-based alias analysis in the compiler and therefore is not reliable.

My question is: what about a union ? If I create the following:

union AtomicInt
{
    int nonatomic;
    std::atomic<int> atomic;
};

AtomicInt x;
x.nonatomic = 5;
x.atomic.compare_exchange_weak(...);

Will this work as intended? Can I manipulate the same memory atomically and non-atomically?


To preempt suggestions about using load(std::memory_order_relaxed) in lieu of non-atomic operations, I've tried the suggestion in this answer to a related question, but it slowed my code down by 50%.

Lock-free atomic primitives are for highly congested concurrency. If there's high congestion, and you start using your atomic variables as non-atomic, you'll definitely introduce bugs, even if on that particular architecture int and atomic<int> has the same layout.

If you have low congestion but require particular ordering in some cases, you should use locks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM