重新排序原子读取 [英] Re-ordering Atomic Reads

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

问题描述

我正在研究一种多阈值算法,该算法读取两个共享的原子变量:

I am working on a multithreded algorithm which reads two shared atomic variables:

std::atomic<int> a(10);
std::atomic<int> b(20);

void func(int key) {
   int b_local = b;
   int a_local = a;
   /* Some Operations on a & b*/
}

算法的不变性是在读取a之前应先读取b.

The invariant of the algorithm is that b should be read before reading a.

问题是,编译器(例如GCC)可以重新排序指令,以便在b之前读取a吗?使用显式的内存隔离将实现此目的,但我想了解的是,是否可以对两个原子负载进行重新排序.

The question is, can compiler(say GCC) re-order the instructions so that a is read before b? Using explicit memory fences would achieve this but what I want to understand is, can two atomic loads be re-ordered.

此外,在完成了Herb Sutter的演讲中的获取/发布语义之后(

Further, after going through Acquire/Release semantics from Herb Sutter's talk(http://herbsutter.com/2013/02/11/atomic-weapons-the-c-memory-model-and-modern-hardware/), I understand that a sequentially consistent system ensures an ordering between acquire(like load) and release(like store). How about ordering between two acquires(like two loads)?

添加有关代码的更多信息: 考虑两个线程T1& T2正在执行:

Adding more info about the code: Consider two threads T1 & T2 executing:

T1:读取b的值,进入睡眠状态

T1 : reads value of b, sleeps

T2:更改a的值,返回

T2 : changes value of a, returns

T1:唤醒并读取a(新值)的新值

T1 : wakes up and reads the new value of a(new value)

现在,考虑重新排序的情况:

Now, consider this scenario with re-ordering:

int a_local =a; int b_local = b;

int a_local =a; int b_local = b;

T1:读取a的值,进入睡眠状态

T1 : reads value of a, sleeps

T2:更改a的值,返回

T2 : changes value of a, returns

T1:对a的值更改一无所知.

T1 : Doesn't know any thing about change in value of a.

问题是像GCC这样的编译器可以重新排序两个原子负载吗?

The question is "Can a compiler like GCC re-order two atomic loads`

推荐答案

说明memory_order_acquire中的>:

Description of memory_order_acquire:

在此加载之前,无法重新排序当前线程中的内存访问.

no memory accesses in the current thread can be reordered before this load.

由于加载b时默认的存储顺序是memory_order_seq_cst,这是最强的顺序,因此从a读取之前不能重新排序,然后再从b读取.

As default memory order when loading b is memory_order_seq_cst, which is the strongest one, reading from a cannot be reordered before reading from b.

即使是较弱的内存顺序(如下面的代码所示)也具有相同的保证:

Even weaker memory orders, as in the code below, provide same garantee:

int b_local = b.load(std::memory_order_acquire);
int a_local = a.load(std::memory_order_relaxed);

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

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