简体   繁体   中英

Any disadvantages for std::atomic_flag not providing load or store operations? (Spin-lock example)

Comparing a std::atomic_flag to an std::atomic_bool (aka std::atomic<bool> ), it seems to me that a std::atomic_flag just has a simpler interface. It provides only testing+setting and clearing the flag while an std::atomic_bool also provides overloads to several operators.

One question of mine is about terminology: What is meant by "load or store operations"? Does it mean that it is not possible to arbitrarily read and modify a std::atomic_flag 's value?

Furthermore, I am wondering, could a std::atomic_bool be faster when being used for a spin-lock? It seems to me that an std::atomic_flag always must read AND write during a spin-lock:

while (my_atomic_flag.test_and_set()); // spin-lock

while an std::atomic_bool would only have to perform a read operation (assuming that the atomic bool is implemented lock-free):

while (my_atomic_bool); // spin-lock

Is an std::atomic_flag strictly more efficient than an std::atomic_bool or could it also be the other way round? What should be used for a spin-lock?

What is meant by "load or store operations"? Does it mean that it is not possible to arbitrarily read and modify a std::atomic_flag's value?

The normal store/load operations are not supported on a std::atomic_flag .
It is a modify-only type; ie. you cannot read-access a std::atomic_flag object without performing a modifying operation.
In general, std::atomic_flag is meant as a building block for other operations. It's interface is deliberately simple; it is the only atomic type that has guaranteed atomic lock-free operations. The operations it supports are:

std::atomic_flag::clear()
std::atomic_flag::test_and_set()

With that, you can easily build your own spinlock (although generally not recommended):

class my_spinlock {
    std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:

    void lock()
    {
        while(flag.test_and_set());
    }

    void unlock()
    {
        flag.clear();
    }
};

Furthermore, I am wondering, could a std::atomic_bool be faster when being used for a spin-lock? It seems to me that an std::atomic_flag always must read AND write during a spin-lock

Well, the thing is, a spinlock always has to modify its state when acquiring the lock. You simply cannot take a lock without telling others.
The implementation for lock() based on a std::atomic<bool> looks very similar:

while (flag.exchange(true)); 

Whether a spinlock based on std::atomic_flag is faster ?
On my platform, the compiler emits the same assembly for both types so I would be very surprised.

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