首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么C++11 acquire_release栅栏不足以实现Dekker同步?

为什么C++11 acquire_release栅栏不足以实现Dekker同步?
EN

Stack Overflow用户
提问于 2014-12-02 11:57:20
回答 2查看 1.3K关注 0票数 16

Dekker风格的同步失败通常是通过重新排序指令来解释的.也就是说,如果我们写

代码语言:javascript
运行
复制
atomic_int X;
atomic_int Y;
int r1, r2;
static void t1() { 
    X.store(1, std::memory_order_relaxed)
    r1 = Y.load(std::memory_order_relaxed);
}
static void t2() {
    Y.store(1, std::memory_order_relaxed)
    r2 = X.load(std::memory_order_relaxed);
}

然后,负载可以与商店重新排序,从而导致r1==r2==0

我原以为会有一个acquire_release栅栏来防止这种重新排序:

代码语言:javascript
运行
复制
static void t1() {
    X.store(1, std::memory_order_relaxed);
    atomic_thread_fence(std::memory_order_acq_rel);
    r1 = Y.load(std::memory_order_relaxed);
}
static void t2() {
    Y.store(1, std::memory_order_relaxed);
    atomic_thread_fence(std::memory_order_acq_rel);
    r2 = X.load(std::memory_order_relaxed);
}

负荷不能在栅栏上方移动,商店不能移动到栅栏下面,因此应该防止不良结果。

然而,实验表明,r1==r2==0仍然可以发生。对此有重新排序的解释吗?我推理中的缺陷在哪里?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-03 10:52:31

据我所知(主要是通过阅读博客),atomic_thread_fence(std::memory_order_acq_rel)可以防止除StoreLoad之外的任何重新排序,也就是说,它仍然允许重新排序带有后续LoadStore。然而,在您的示例中,这正是必须防止的重新排序。

更准确地说,atomic_thread_fence(std::memory_order_acquire)防止将任何先前的Load与任何后续的Store和任何后续的Load重新排序,也就是说,它防止了跨越栅栏的LoadLoadLoadStore重新排序。

atomic_thread_fence(std::memory_order_release)防止将任何后续的Store与任何前面的Store和任何前面的Load重新排序,也就是说,它阻止了跨越栅栏的LoadStoreStoreStore重新排序。

然后,atomic_thread_fence(std::memory_order_acq_rel)阻止联合,即阻止LoadLoadLoadStoreStoreStore,这意味着只有StoreLoad仍然可能发生。

票数 12
EN

Stack Overflow用户

发布于 2014-12-02 15:50:14

实际上,memory_order_acq_rel的行为就像在同一个地方获取和释放围栏一样。但问题是,他们并没有阻止所有可能的重新排序,他们阻止随后的货物或先前的商店被重新订购围绕围栏。因此,先前的负荷和随后的存储仍然可以通过栅栏。

在Dekker同步中,重要的是要防止负载在另一个线程中的存储前被重新排序,即在栅栏之前。现在,在发生同步的地方展开您的循环,您将得到来自前一个迭代的负载可以在当前迭代中通过栅栏。

memory_order_seq_cst可以很好地实现Dekker的同步,因为它可以防止跨越这一点的任何重新排序。例如,tbb使用Dekker的算法和mfence来窃取工作。

想要更好的理解,请参阅Herb讲座"Atomic<> weapons 1/2“中的伟大动画,在0:43。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27248856

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档