C++0x | Why std::atomic overloads each method with the volatile-qualifier?

不问归期 提交于 2019-12-08 19:28:55

问题


The following excerpt from the current draft shows what I mean:

namespace std {
    typedef struct atomic_bool {
        bool is_lock_free() const volatile;
        bool is_lock_free() const;
        void store(bool, memory_order = memory_order_seq_cst) volatile;
        void store(bool, memory_order = memory_order_seq_cst);
        bool load(memory_order = memory_order_seq_cst) const volatile;
        bool load(memory_order = memory_order_seq_cst) const;
        operator bool() const volatile;
        operator bool() const;
        bool exchange(bool, memory_order = memory_order_seq_cst) volatile;
        bool exchange(bool, memory_order = memory_order_seq_cst);
        bool compare_exchange_weak(bool&, bool, memory_order, memory_order) volatile;
        bool compare_exchange_weak(bool&, bool, memory_order, memory_order);
        bool compare_exchange_strong(bool&, bool, memory_order, memory_order) volatile;
        bool compare_exchange_strong(bool&, bool, memory_order, memory_order);
        bool compare_exchange_weak(bool&, bool, memory_order = memory_order_seq_cst) volatile;
        bool compare_exchange_weak(bool&, bool, memory_order = memory_order_seq_cst);
        bool compare_exchange_strong(bool&, bool, memory_order = memory_order_seq_cst) volatile;
        bool compare_exchange_strong(bool&, bool, memory_order = memory_order_seq_cst);
        atomic_bool() = default;
        constexpr atomic_bool(bool);
        atomic_bool(const atomic_bool&) = delete;
        atomic_bool& operator=(const atomic_bool&) = delete;
        atomic_bool& operator=(const atomic_bool&) volatile = delete;
        bool operator=(bool) volatile;
    } atomic_bool;
}

Volatile is transitive. Thus, you cannot call a non-volatile member function from a volatile object. On the other hand, calling a volatile member function from a non-volatile object is allowed.

So, is there any implementation difference between the volatile and non-volatile member functions in the atomic classes? In other words, is there any need for the non-volatile overload?


回答1:


I think that the volatile overloads exist for efficiency reasons. Volatile reads and writes are inherently more expensive than non-volatile reads and writes in C++0x, since the memory model puts some stringent requirements that prevent caching of values of volatile variables. If all the functions were only marked volatile, then the code couldn't necessarily make certain optimizations that would otherwise improve performance. Having the distinction allows the compiler to optimize non-volatile reads and writes when possible while degrading gracefully when volatile reads and writes are required.




回答2:


First, it sounds redundant to make a volatile std::atomic. Actually, I can imagine an useful situation. Assuming we have an fixed device (memory-)address we want to operate on. Due to the fact that the std::atomic_xxx classes as well as the std::atomic<> template class sizes should be same size as their corresponding built-in-types, you might want to handle both: Performing atomic operations with control over memory ordering and make sure that the access to our atomic-object is never optimized. Thus, we could declare something like:

std::atomic<long> volatile* vmem_first4 = reinterpret_cast<std::atomic<long> volatile*>(0xxB8000);


来源:https://stackoverflow.com/questions/4870869/c0x-why-stdatomic-overloads-each-method-with-the-volatile-qualifier

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!