从C++ 11开始就知道有6个内存顺序,在有关std::memory_order_acquire
的文档中:
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:
一些文章包含一张图片,展示了获取释放语义的本质。这很容易理解,但是会引起困惑。
例如,我们可能认为
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
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)之间的关系。