从C++ 11开始就知道有6个内存顺序,在有关std::memory_order_acquire的文档中:

  • http://en.cppreference.com/w/cpp/atomic/memory_order



  • 1.非原子负载可以在atomic-acquire-load之后重新排序:

    IE。它不保证非原子负载在获得原子负载后不能重新排序。
    static std::atomic<int> X;
    static int L;
    ...
    
    void thread_func()
    {
        int local1 = L;  // load(L)-load(X) - can be reordered with X ?
    
        int x_local = X.load(std::memory_order_acquire);  // load(X)
    
        int local2 = L;  // load(X)-load(L) - can't be reordered with X
    }
    

    加载int local1 = L;可以在X.load(std::memory_order_acquire);之后重新排序吗?

    2.我们可以认为在atomic-acquire-load之后不能重新排序非atomic-load:

    一些文章包含一张图片,展示了获取释放语义的本质。这很容易理解,但是会引起困惑。

    c&#43;&#43; - 非原子负载可以在原子获取负载之后重新排序吗?-LMLPHP

    c&#43;&#43; - 非原子负载可以在原子获取负载之后重新排序吗?-LMLPHP

    例如,我们可能认为std::memory_order_acquire无法重新排序任何系列的Load-Load操作,即使在atomic-acquire-load之后也无法重新排序非atomic-load。

    3.非原子负载可以在atomic-acquire-load之后重新排序:

    澄清的一件好事:Acquire语义可以防止按读取顺序在之后跟着的读取或后面的写入操作来对读取-acquire进行内存重新排序。 http://preshing.com/20120913/acquire-and-release-semantics/

    但还有known, that:在强序系统( x86 ,SPARC TSO,IBM大型机)上,发布-获取顺序对于大多数操作都是自动

    第34页的Herb Sutter显示:https://onedrive.live.com/view.aspx?resid=4E86B0CF20EF15AD!24884&app=WordPdf&authkey=!AMtj_EflYn2507c

    c&#43;&#43; - 非原子负载可以在原子获取负载之后重新排序吗?-LMLPHP

    4.即再次,我们可以认为在atomic-acquire-load之后不能重新排序非atomic-load:

    IE。对于x86:
  • 版本-获取,对于大多数操作
  • 是自动订购的
  • 读取不会与读取的任何读取一起重新排序。 (任意-即无论年龄大小与否)

  • 那么在C++ 11中非原子负载可以在atomic-acquire-load之后重新排序吗?

    最佳答案

    您引用的引用非常清楚:在加载之前您不能移动读取。在您的示例中:

    static std::atomic<int> X;
    static int L;
    
    
    void thread_func()
    {
        int local1 = L;  // (1)
        int x_local = X.load(std::memory_order_acquire);  // (2)
        int local2 = L;  // (3)
    }
    
    memory_order_acquire表示(3)不能在(2)之前发生((2)中的加载在(3)中thr加载之前被排序)。它没有说(1)和(2)之间的关系。

    10-07 20:20