原子操作有多昂贵?

kra*_*mir 7 cpu multithreading atomic atomicity

我正在深入研究多线程编程并考虑使用原子操作进行无锁引用计数。

很明显,至少在恒定规模上,原子操作可能比非原子操作慢。我担心的是其他 CPU 同步来执行原子操作。

我想知道在核心 A 上执行原子操作是否(如果,以及多少)影响其他核心的性能,其中:

  1. 与核心 A 无关
  2. 正在执行与核心 A 相同进程的不同线程
  3. 正在执行原子操作
  4. 正在执行原子操作并且正在执行与核心 A 相同进程的不同线程
  5. 正在执行任何与内存相关的操作,即。加载、存储、...
  6. 在与核心 A 相同的内存区域(缓存行,页面?)中执行任何与内存相关的操作

Ser*_*eyA 5

很多人认为原子操作很便宜。然而,这不一定正确,因为原子操作是一种概括。有 3 种基本类型的原子操作:

  1. 原子保存
  2. 原子负荷
  3. Atomic CompareAndSet(递增/递减/等)

前两个通常或多或少便宜(或者,众所周知,其成本与英特尔的非原子朋友完全相同)。它们确实施加了内存屏障,但这些屏障仅与执行它们的 CPU 相关,并且 CPU 正在努力使屏障高效。然而,第三个在竞争中可能并不便宜。Atomic CAS 和朋友实际上在循环中执行操作,直到成功,因此在争用情况下可能需要大量时间来执行操作。


Dav*_*rtz 5

我正在将原子读-修改-写操作与现代 x86 CPU 上的相应非原子操作进行比较。

与核心 A 无关

没有效果。

正在执行与核心 A 相同进程的不同线程

没有效果。

正在执行原子操作

没有效果。

正在执行原子操作并且正在执行与核心 A 相同进程的不同线程

没有效果。

正在执行任何与内存相关的操作,即。加载、存储、...

没有效果。

在与核心 A 相同的内存区域(缓存行,页面?)中执行任何与内存相关的操作

缓存线必须由执行原子操作的内核独占获取(从缓存中拥有它的任何其他内核中窃取它),并且在原子操作完成以缓存和交互之前不能被另一个内核访问缓存流量同步它,以便它在另一个核心中共享或独占。

原子操作的主要成本是执行原子指令的内核的流水线。因为原子操作必须在一个明确定义的地方同时发生,所以它(大部分)不能与其他操作重叠。对于通过在处理的各个阶段保留大量指令来提高性能的超标量 CPU 来说,这是一个巨大的损失。