- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
从链接:
What is the difference between load/store relaxed atomic and normal variable?
这个回答给我留下了深刻的印象:
Using an atomic variable solves the problem - by using atomics allthreads are guarantees to read the latest writen-value even if thememory order is relaxed.
atomic<int*> Guard(nullptr);
int Payload = 0;
线程1:
Payload = 42;
Guard.store(&Payload, memory_order_release);
线程2:
g = Guard.load(memory_order_consume);
if (g != nullptr)
p = *g;
atomic<int*> Guard(nullptr);
volatile int Payload = 0; // 1.Payload is volatile now
// 2.Payload.assign and Guard.store in order for data dependency
Payload = 42;
Guard.store(&Payload, memory_order_release);
// 3.data Dependency make w/r of g/p in order
g = Guard.load(memory_order_relaxed);
if (g != nullptr)
p = *g; // 4. For 1,2,3 there are no reorder, and here, volatile Payload make the value of 42 is visable.
附加内容(由于 Sneftel 的回答):
Using an atomic variable solves the problem - by using atomics allthreads are guarantees to read the latest writen-value even if thememory order is relaxed.
In fact, atomics are always thread safe, regardless of the memoryorder! The memory order is not for the atomics -> it's for non atomicdata.
When you use consume semantics, you’re basically trying to make thecompiler exploit data dependencies on all those processor families.That’s why, in general, it’s not enough to simply changememory_order_acquire to memory_order_consume. You must also make surethere are data dependency chains at the C++ source code level.
最佳答案
首先,memory_order_consume
ISO C++ 委员会暂时不鼓励,直到他们提出编译器可以实际实现的东西。几年来,编译器处理过 consume
作为 acquire
的同义词. 请参阅此答案底部的部分。
硬件仍然提供数据依赖性,因此尽管目前没有任何安全可移植的 ISO C++ 方法可以利用,但讨论这一点很有趣。 (仅使用 mo_relaxed
或手动原子进行 hack,以及基于对编译器优化和 asm 的理解的仔细编码,有点像您尝试使用轻松的方式。但您不需要 volatile。)
Oh, maybe it uses data dependencies to prevent reordering of instructions while ensuring the visibility of Payload?
consume
是对此的优化:只要您遵循一些依赖性规则,就可以让编译器利用硬件保证来避免读取器中的内存障碍。)
volatile
有一些误解。确实,我在问题下评论过。发布存储确保早期的非原子分配在内存中可见。
mo_relaxed
是一种糟糕的方式。见还有
https://software.rajivprab.com/2018/04/29/myths-programmers-believe-about-cpu-caches/ )
release
只需要确保本地 CPU 存储以正确的顺序全局可见(提交到 L1d 缓存)。 ISO C++ 没有指定任何该级别的详细信息,并且假设可能会有一个工作方式非常不同的实现。
What does memory_order_consume really do?
mo_consume
这样做是为了确保编译器在底层硬件不自然/免费提供依赖顺序的实现上使用屏障指令。实际上,这意味着仅在 DEC Alpha 上。
Dependent loads reordering in CPU/
Memory order consume usage in C11
[[carries_dependency]]
标签)。这样的代码可能会取代
x-x
具有常数
0
并优化掉,失去数据依赖性。但是知道依赖关系的代码必须使用类似
sub r1, r1, r1
的东西。获取具有数据依赖性的零的指令。
relaxed
将在 Alpha 以外的 ISA 上实际工作),但是
mo_consume
的纸上设计允许需要与编译器通常会做的不同的代码生成的各种东西。这是使高效实现如此困难的部分原因,编译器只是将其提升为
mo_acquire
.
kill_dependency
和/或
[[carries_dependency]]
到处都是,否则你最终会在函数边界处遇到障碍。这些问题导致 ISO C++ 委员会暂时劝阻
consume
.
consume
旨在暴露给软件。乱序 exec 无论如何只能重新排序独立的工作,而不是在知道加载地址之前开始加载,所以在大多数 CPU 上强制执行依赖排序无论如何都是免费的:只有少数 DEC Alpha 模型可能违反因果关系并有效加载数据从之前它有给它地址的指针。 release
+
consume
不管波动。在实践中使用
release
在大多数编译器和大多数 ISA 上都是安全的商店 +
relaxed
加载,当然 ISO C++ 没有说明该代码的正确性。但就目前的编译器状态而言,这是某些代码(如 Linux 内核的 RCU)造成的。
关于c++ - memory_order_consume 到底有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65336409/
从链接: What is the difference between load/store relaxed atomic and normal variable? 这个回答给我留下了深刻的印象: U
我正在查看有关原子操作和发生前关系的 Boost 示例,但我有点困惑。在“通过发布和消费发生之前”部分,有以下示例,他们说这是错误的,但我看不到: atomic a(0); complex_data_
我有一个关于 GCC-Wiki article 的问题.在标题“Overall Summary”下,给出了以下代码示例: 线程 1: y.store (20); x.store (10); 线程 2:
我正在阅读 C++ Concurrency in Action安东尼·威廉姆斯。目前我在他描述 memory_order_consume 的地方。 在那 block 之后有: Now that I’v
我现在正在学习C++11 memory order model并想了解 memory_order_relaxed 和 memory_order_consume 之间的区别。 具体来说,我正在寻找一个无
在试图理解如何处理无锁代码的过程中,我尝试编写一个单一消费者/单一生产者无锁队列。一如既往,我检查了论文、文章和代码,特别是考虑到这是一个有点微妙的主题。 所以,我在 Folly 库中偶然发现了这个数
我是一名优秀的程序员,十分优秀!