C ++标准表示对原子的RMW(读 - 修改 - 写)操作将对原子变量的最新值进行操作。因此,当从多个线程并发执行时,对这些操作使用memory_order_relaxed不会影响RMW操作。
我假设只有当RMW操作存在一些内存屏障或栅栏时才会出现这种行为,即使指定的内存顺序是"放松"。如果我的理解错误,请纠正我,并解释如果没有使用这样的内存屏障,这些操作如何处理最新值。如果我的理解是正确的,那么我可以进一步假设使用Acquire-Release或Seq-CST内存顺序不应该为RMW操作提供额外的性能命中,比如ARM或Alpha这样的弱有序体系结构。提前谢谢。
答案 0 :(得分:3)
这是一个遗憾的关于原子记忆顺序的常见误解。请参阅,那些不适用于实际的原子操作。它们适用于他们周围的其他操作。
例如:
//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;
那么,这是做什么的?线程2在线程1上等待表示value
已更新,然后线程2读取value
。
<order_write>
和<order_read>
不管理原子变量如何被看到的行为。它控制在看到原子操作之前设置的非原子值的行为。
为了使此代码有效,<order_write
&gt; 必须使用至少与memory_order_release
一样强的内存顺序。并且<order_read>
必须使用至少与memory_order_acquire
一样强的内存顺序。
这些内存顺序会影响value
的传输方式,不原子值的行为方式。
不会&#34;对最新值进行操作&#34;需要像记忆障碍这样的东西吗?
大多数架构不太可能使用全局内存屏障来实现原子。这就是非宽松记忆命令的作用:它们对作者和读者施加了一般的记忆障碍。
原子操作,如果他们需要内存屏障才能工作,通常会使用本地内存屏障。也就是说,一个特定于原子变量地址的障碍。
因此,可以合理地假设非宽松的内存顺序会比轻松的内存顺序损害性能。这当然不是保证,但它是一个非常好的一阶逼近。
原子实现可能可能使用完整的全局内存屏障吗?是。但是如果一个实现转向基本原子类型的实现,那么该架构可能没有其他选择。因此,如果您的算法需要原子操作,那么您实际上没有其他选择。