MS *_*nth 4 c++ multithreading memory-model compare-and-swap stdatomic
C++ 标准说,原子上的 RMW(读-修改-写)操作将对原子变量的最新值进行操作。因此memory_order_relaxed,当从多个线程并发执行时,使用这些操作不会影响 RMW 操作。
我假设只有当 RMW 操作存在一些内存屏障或栅栏时,即使指定的内存顺序是“放松的”,这种行为也是可能的。如果我的理解有误,请纠正我,并解释如果不使用此类内存屏障,这些操作如何处理最新值。如果我的理解是正确的,那么我是否可以进一步假设使用 Acquire-Release 或 Seq-CST 内存顺序不应该对 RMW 操作产生额外的性能影响,比如 ARM 或 Alpha 等弱排序架构。提前致谢。
不幸的是,这是对原子内存顺序的常见误解。看,那些并不(完全)适用于实际的原子操作。它们主要适用于它们周围的其他操作。
例如:
//accessible from anywhere
std::atomic<bool> flag;
int value = 0;
//code in thread 1:
value = 1;
flag.store(true, <order_write>);
//code in thread 2:
bool true_val = true;
while(!flag.compare_exchange_weak(true_val, false, <order_read>);
int my_val = value;
Run Code Online (Sandbox Code Playgroud)
那么,这是在做什么呢?线程 2 正在等待线程 1 发出value已更新的信号,然后线程 2 读取value。
<order_write>并且<order_read>不控制如何看待特定原子变量的行为。它控制如何看到在原子操作之前/之后设置的其他值的行为。
为了使此代码工作,<order_write>必须使用至少与memory_order_release. 并且<order_read> 必须使用至少与memory_order_acquire.
这些内存顺序影响如何value传输(或者更具体地说,在原子写入之前设置的东西)。
“对最新值进行操作”的条件不需要内存屏障之类的东西吗?
大多数架构不太可能使用全局内存屏障来实现实际的原子修改。它需要非宽松的内存命令才能做到这一点:它们对作者和读者强加了一般的内存障碍。
原子操作,如果它们需要内存屏障来工作,通常会使用本地内存屏障。也就是说,特定于原子变量地址的屏障。
因此可以合理地假设非宽松的内存顺序比宽松的内存顺序对性能的影响更大。这当然不是一个保证,但它是一个非常好的一阶近似值。
原子实现是否可以在任何原子操作上使用完整的全局内存屏障?是的。但是如果一个实现诉诸于基本原子类型,那么架构可能别无选择。所以如果你的算法需要原子操作,你真的没有其他选择。
| 归档时间: |
|
| 查看次数: |
595 次 |
| 最近记录: |