繁体   English   中英

C++ 原子抢占安全吗?

[英]Are C++ atomics preemption safe?

根据我对原子的理解,它们是特殊的汇编指令,可保证 SMP 系统中的两个处理器不能同时写入同一个 memory 区域。 例如,在 PowerPC 中,原子增量看起来像:

retry:
  lwarx  r4, 0, r3 // Read integer from RAM location r3 into r4, placing reservation.
  addi   r4, r4, 1 // Add 1 to r4.
  stwcx. r4, 0, r3 // Attempt to store incremented value back to RAM.
  bne-   retry     // If the store failed (unlikely), retry.

但是,这并不能保护四个指令不被中断抢占,并安排另一个任务。为了防止抢占,您需要在输入代码之前执行中断锁定。

从我对C++ atomics的了解来看,它们似乎在需要时强制执行锁。 所以我的第一个问题是——

  1. C++ 标准是否保证在原子操作期间不会发生抢占? 如果是这样,我在标准中的哪里可以找到这个?

我检查了我的英特尔 PC 上的atomic<int>::is_always_lock_free ,它true了。 根据我对上述装配块的假设,这让我感到困惑。 在深入研究英特尔程序集(我不熟悉)之后,我发现lock xadd DWORD PTR [rdx], eax正在发生。 所以我的问题是——

  1. 某些架构是否提供了保证不抢占的原子相关指令? 还是我的理解有误?

最后我想知道compare_exchange_weakcompare_exchange_strong语义 -

  1. 区别在于重试机制还是其他原因?

编辑:阅读答案后,我对另一件事感到好奇

  1. 原子成员 function 操作fetch_addoperator++等它们是强还是弱?

C++ 标准是否保证在原子操作期间不会发生抢占? 如果是这样,我在标准中的哪里可以找到这个?

不,它没有。 由于代码确实无法判断这是否发生(根据情况,在原子操作之前或之后与抢占没有区别),因此没有理由这样做。

某些架构是否提供了保证不抢占的原子相关指令? 还是我的理解有误?

没有意义,因为无论如何操作必须看起来是原子的,因此在观察到的行为中的抢占总是与之前或之后的抢占相同。 如果您编写的代码曾经看到原子操作期间的抢占导致可观察到的效果不同于之前的抢占或之后的抢占,那么该平台就会被破坏,因为该操作的行为不是原子的。

这类似于这个问题: std::atomic 中的任何内容都是免等待的?

以下是 lock-freedom 和 wait-freedom 的一些定义(均取自Wikipedia ):

如果当程序线程运行足够长的时间时,至少有一个线程取得进展,则算法是无锁的

如果每个操作都限制了算法在操作完成之前将采取的步数,则该算法是无等待的

您的带有重试循环的代码是无锁的:如果存储失败,线程只需要执行重试,但这意味着该值必须同时更新,因此其他线程必须取得进展。

关于无锁,线程是否可以在原子操作的中间被抢占并不重要。

某些操作可以转换为单个原子操作,在这种情况下,此操作是无等待的,因此不能在中途被抢占。 但是,哪些操作实际上无需等待取决于编译器和目标体系结构(如我在引用的 SO 问题中的回答中所述)。

关于compare_exchange_weakcompare_exchange_strong之间的区别 - 弱版本可能会虚假失败,即,即使比较实际上是真的,它也可能会失败。 这可能发生在具有 LL/SC 的架构上。 假设我们使用compare_exchange_weak用期望值A更新某个变量。 LL 从变量中加载值A ,在执行 SC 之前,将变量更改为B ,然后再返回A 因此,即使变量包含与以前相同的值,对B的中间更改也会导致 SC(以及因此compare_exchange_weak )失败。 compare_exchange_strong不能虚假失败,但要实现它必须在具有 LL/SC 的体系结构上使用重试循环。

我不完全确定fetch_add是“强还是弱”是什么意思。 fetch_add不会失败- 它只是通过添加提供的值来执行某个变量的原子更新,并返回变量的旧值。 是否可以将其转换为单个指令(如在 Intel 上)或转换为具有 LL/SC(Power)或 CAS(Sparc)的重试循环取决于目标体系结构。 无论哪种方式,都可以保证正确更新变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM