- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
引用以下代码
auto x = std::atomic<std::uint64_t>{0};
auto y = std::atomic<std::uint64_t>{0};
// thread 1
x.store(1, std::memory_order_release);
auto one = y.load(std::memory_order_seq_cst);
// thread 2
y.fetch_add(1, std::memory_order_seq_cst);
auto two = x.load(std::memory_order_seq_cst);
这里有没有可能one
和two
都是0?
(我似乎遇到了一个错误,如果 one
和 two
在上面的代码运行后都可以保持 0 的值,则可以解释这个错误。以及规则排序太复杂了,我无法弄清楚上面可能的排序。)
最佳答案
是的,两个负载都有可能得到 0
。
在线程 1 中,y.load
可以“传递”x.store(mo_release)
,因为它们不是 seq_cst。 ISO C++ 保证必须存在的 seq_cst 操作的全局总顺序仅包括 seq_cst 操作。
(就普通 CPU 的硬件/CPU 架构而言,负载可以在发布存储离开存储缓冲区之前从连贯缓存中获取值。在这种情况下,我发现根据我怎么知道它是为 x86(或 to generic release and acquire operations)编译的,然后应用 asm 内存排序规则。应用这个推理假设正常的 C++->asm mappings 是安全的,并且总是至少与 C++ 内存模型一样强大。如果你可以通过这种方式找到合法的重新排序,你不需要费力地通过 C++ 形式主义。但如果你不这样做,那当然不能证明它在 C++ 抽象机中是安全的。)
无论如何,要意识到的关键点是 seq_cst 操作不像 atomic_thread_fence(mo_seq_cst)
- 单个 seq_cst
操作只有以它们与其他 seq_cst
操作交互的方式恢复/保持顺序一致性,而不是与普通的获取/释放/acq_rel。 (同样,获取和释放栅栏是更强的双向障碍,不同于获取和释放操作 Jeff Preshing explains。)
这是唯一可能的重新排序;其他可能性只是两个线程的程序顺序的交错。让商店最后“发生”(变得可见)导致 0, 0
结果。
我将 one
和 two
重命名为 r1
和 r2
(每个线程中的本地“寄存器”),避免写类似 one == 0
的东西。
// x=0 nominally executes in T1, but doesn't have to drain the store buffer before later loads
auto r1 = y.load(std::memory_order_seq_cst); // T1b r1 = 0 (y)
y.fetch_add(1, std::memory_order_seq_cst); // T2a y = 1 becomes globally visible
auto r2 = x.load(std::memory_order_seq_cst); // T2b r2 = 0 (x)
x.store(1, std::memory_order_release); // T1a x = 0 eventually becomes globally visible
这实际上可能发生在 x86 上,但有趣的是不会发生在 AArch64 上。 x86 可以在没有额外障碍的情况下进行 release-store(只是一个普通的 store),seq_cst 加载的编译方式与 plain acquire 相同,只是一个普通的加载。
在 AArch64 上,release 和 seq_cst 存储使用 STLR。 seq_cst 加载使用 LDAR,它与 STLR 有特殊的交互,在最后一个 STLR 从存储缓冲区中耗尽之前不允许读取缓存。所以 ARMv8 上的 release-store/seq_cst load 和 seq_cst store/seq_cst load 是一样的。 (ARMv8.3 添加了 LDAPR,通过让获取加载以不同方式编译来允许真正的获取/释放;参见 this Q&A。)
然而,它也可能发生在许多使用单独屏障指令的 ISA 上,例如 ARM32:发布存储通常会使用屏障完成,然后是普通存储,以防止重新排序较早加载/商店,但不会停止重新订购。如果 seq_cst 加载避免在自身之前需要一个完整的屏障(这是正常情况),那么存储可以在加载后重新排序。
例如,ARMv7 上的发布存储是 dmb ish; str
,一个seq_cst负载是ldr; dmb ish
,所以你有 str/ldr,它们之间没有障碍。
在 PowerPC 上,因为 seq_cst 负载是 hwsync; ld;厘米;公元前; isync
,所以在加载之前有一个完整的屏障。 (我认为 HeavyWeight Sync 是防止 IRIW 重新排序的一部分,用于阻止同一物理内核上的 SMT 线程之间的存储转发,只有当它们实际上变得全局可见时才能看到来自其他内核的存储。)
关于c++ - memory_order_seq_cst 和 memory_order_release 的可能排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67693687/
C++ 支持原子线程栅栏,即保证使用 std::atomic<> 的线程属性的栅栏。操作,具有函数 atomic_thread_fence 。它需要一个内存顺序参数来调整栅栏的“强度”。 我知道,当并
有没有表格总结一下内存顺序的区别?比如每种内存顺序在什么情况下使用 此外,内存顺序和(data_cond和future)有什么区别? is it 1. memory order is for wait
如果使用单个原子变量和 std::memory_order_seq_cst,是否保证非原子操作不会被重新排序? 例如,如果我有 std::atomic quux = {false}; void foo
在多线程程序中,如果只有一个线程使用它,您是否从 memory_order_seq_cst 得到任何保证,即您不会从较弱的顺序中得到保证?示例: #include extern atomic_int
我对C11的阅读spec with regards to atomic operation ordering建议 memory_order_seq_cst适用于对特定原子对象的操作。 大多数情况下,描
我从以下位置获取了有关 std::memory_order_seq_cst 的示例: http://en.cppreference.com/w/cpp/atomic/memory_order #inc
完全/通用内存屏障是指相对于系统其他组件而言,屏障之前指定的所有LOAD和STORE操作似乎都发生在屏障之后指定的所有LOAD和STORE操作之前的情形。 根据cppreference,memory_
我已经阅读了 c++11 标准中关于内存排序的章节,但对规则感到困惑。根据C++11标准(ISO/IEC JTC1 SC22 WG21 N3690),29.3 3,据说: There shall be
引用以下代码 auto x = std::atomic{0}; auto y = std::atomic{0}; // thread 1 x.store(1, std::memory_order_re
引用以下代码 auto x = std::atomic{0}; auto y = std::atomic{0}; // thread 1 x.store(1, std::memory_order_re
存储是释放操作,加载是两者的获取操作。我知道 memory_order_seq_cst 是为了对所有操作施加额外的总排序,但我没有建立一个例子,如果所有 memory_order_seq_cst替换为
我的代码: std::atomic x(22) , y(22); int temp_x = -1, temp_y = -1; void task_0(){ x.store(33, std:
我正在玩 C++ Concurrency in Action 中的一个示例,它使用 std::memory_order_relaxed 从 5 个不同的线程读取和写入 3 个原子变量。示例程序如下:
我正在玩 C++ Concurrency in Action 中的一个示例,它使用 std::memory_order_relaxed 从 5 个不同的线程读取和写入 3 个原子变量。示例程序如下:
我创建了一个简单的测试来检查 std::memory_order_relaxed比 std::memory_order_seq_cst 快atomic 的值增量。然而,这两种情况的性能是相同的。 我的
使用基本的简化版本 seqlock , gcc 将非原子负载重新排序到原子 load(memory_order_seq_cst)使用 -O3 编译代码时.当使用其他优化级别编译或使用 clang 编译
Why does this `std::atomic_thread_fence` work的后续问题 由于虚拟互锁操作优于_mm_mfence,并且有很多方法可以实现它,哪个互锁操作以及应使用哪些数据
来自 c++11 29.3-p3: There shall be a single total order S on all memory_order_seq_cst operations, cons
我正在研究 Google 的灯丝作业系统。目前,我正在研究他们实现的 WorkStealingDequeue。您可以查看完整的源代码here .这个数据结构是基于这个work .在他们的 pop 和
作为Anthony Williams said : some_atomic.load(std::memory_order_acquire) does just drop through to a si
我是一名优秀的程序员,十分优秀!