原子获取负载后可以重新排序非原子负载吗? [英] Can non-atomic-load be reordered after atomic-acquire-load?

查看:172
本文介绍了原子获取负载后可以重新排序非原子负载吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于C ++ 11中已知有6个内存顺序,并且在有关 std :: memory_order_acquire 的文档中:








  • 例如,我们可能认为 std :: memory_order_acquire 不能重新排序任何系列的Load-Load操作,即使非原子负载在原子获取负载后也不能重新排序。



    3。非原子负载可以在原子获取负载之后重新排序:



    好的事情是澄清:获取语义防止read-以读取或以程序顺序跟随其后的写入操作获取。



    4。也就是说再次,我们可以认为非原子负载在原子获取负载之后不能被重新排序:



    对于x86:




    • 发布 - 获取订单是大多数操作的自动订阅

    • 读取未按任何读取顺序重新排序。 (任何 - 不管是否是旧的)



    因此,在C中的原子获取负载之后可以重新排序非原子负载++ 11?

    解决方案

    引用的引用很清楚:在您的示例中:

      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)之前发生(在(3)中的thr负载之前,(2)中的负载被排序)。它没有说明(1)和(2)之间的关系。


    As known in since C++11 there are 6 memory orders, and in documentation written about std::memory_order_acquire:

    memory_order_acquire

    A load operation with this memory order performs the acquire operation on the affected memory location: no memory accesses in the current thread can be reordered before this load. This ensures that all writes in other threads that release the same atomic variable are visible in the current thread.

    1. Non-atomic-load can be reordered after atomic-acquire-load:

    I.e. it does not guarantee that non-atomic-load can not be reordered after acquire-atomic-load.

    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
    }
    

    Can load int local1 = L; be reordered after X.load(std::memory_order_acquire);?

    2. We can think that non-atomic-load can not be reordered after atomic-acquire-load:

    Some articles contained a picture showing the essence of acquire-release semantics. That is easy to understand, but can cause confusion.

    For example, we may think that std::memory_order_acquire can't reorder any series of Load-Load operations, even non-atomic-load can't be reordered after atomic-acquire-load.

    3. Non-atomic-load can be reordered after atomic-acquire-load:

    Good thing that there is clarified: Acquire semantics prevent memory reordering of the read-acquire with any read or write operation which follows it in program order. http://preshing.com/20120913/acquire-and-release-semantics/

    But also known, that: On strongly-ordered systems (x86, SPARC TSO, IBM mainframe), release-acquire ordering is automatic for the majority of operations.

    And Herb Sutter on page 34 shows: https://onedrive.live.com/view.aspx?resid=4E86B0CF20EF15AD!24884&app=WordPdf&authkey=!AMtj_EflYn2507c

    4. I.e. again, we can think that non-atomic-load can not be reordered after atomic-acquire-load:

    I.e. for x86:

    • release-acquire ordering is automatic for the majority of operations
    • Reads are not reordered with any reads. (any - i.e. regardless of older or not)

    So can non-atomic-load be reordered after atomic-acquire-load in C++11?

    解决方案

    The reference you cited is pretty clear: you can't move reads before this load. In your example:

    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 means that (3) cannot happen before (2) (the load in (2) is sequenced before thr load in (3)). It says nothing about the relationship between (1) and (2).

    这篇关于原子获取负载后可以重新排序非原子负载吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆