gpt4 book ai didi

multithreading - 为什么 C++11acquire_release 栅栏不足以用于 Dekker 同步?

转载 作者:行者123 更新时间:2023-12-03 20:45:20 26 4
gpt4 key购买 nike

Dekker 式同步的失败通常用指令的重新排序来解释。即,如果我们写

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 栅栏来防止这种重新排序:
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);
}

cargo 不能移动到围栏上方,商店不能移动到围栏下方,因此应防止出现不良结果。

然而,实验显示 r1==r2==0仍然可以发生。对此是否有基于重新排序的解释?我的推理有什么缺陷?

最佳答案

据我了解(主要来自阅读 Jeff Preshings blog ),一个 atomic_thread_fence(std::memory_order_acq_rel)防止除 StoreLoad 之外的任何重新排序,即它仍然允许重新排序 Store带有后续 Load .但是,这正是您的示例中必须防止的重新排序。

更准确地说,一个 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)然后阻止联合,即阻止 LoadLoad , LoadStore , 和 StoreStore ,这意味着只有 StoreLoad可能仍然会发生。

关于multithreading - 为什么 C++11acquire_release 栅栏不足以用于 Dekker 同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27248856/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com