重新排序原子读取 [英] Re-ordering Atomic Reads
问题描述
我正在研究一种多阈值算法,该算法读取两个共享的原子变量:
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屋!