7

当前草案的以下摘录说明了我的意思:

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 和 non-volatile 成员函数在实现上有什么区别吗?换句话说,是否需要非易失性重载?

4

2 回答 2

4

我认为出于效率原因存在易失性过载。易失性读写在本质上比 C++0x 中的非易失性读写更昂贵,因为内存模型提出了一些严格的要求,以防止缓存易失性变量的值。如果所有函数都只标记为 volatile,则代码不一定会进行某些优化,否则会提高性能。有了这种区别,编译器就可以在可能的情况下优化非易失性读取和写入,同时在需要易失性读取和写入时优雅地降级。

于 2011-02-02T04:52:45.947 回答
-1

首先,制作一个 volatile 的 std::atomic 听起来是多余的。实际上,我可以想象一个有用的情况。假设我们有一个要操作的固定设备(内存)地址。由于 std::atomic_xxx 类以及 std::atomic<> 模板类的大小应该与其相应的内置类型大小相同,您可能希望同时处理这两者:执行原子操作并控制内存排序并确保对我们的原子对象的访问永远不会优化。因此,我们可以声明如下:

std::atomic<long> volatile* vmem_first4 = reinterpret_cast<std::atomic<long> volatile*>(0xxB8000);
于 2011-02-03T04:13:32.707 回答