为什么CAS(原子)操作比同步或易失操作更快

时间:2013-10-27 20:18:07

标签: atomic compare-and-swap

据我所知,synchronized关键字将本地线程缓存与主内存同步。 volatile关键字基本上总是在每次访问时从主内存中读取变量。当然,访问主内存比本地线程缓存昂贵得多,因此这些操作很昂贵。但是,CAS操作使用低级硬件操作但仍必须访问主存储器。那么CAS操作如何更快?

3 个答案:

答案 0 :(得分:2)

我认为关键因素是你所说的 - CAS机制使用低级硬件指令,允许最小的缓存刷新和争用解决。

其他两种机制(synchronizationvolatile)使用不同的体系结构技巧,这些技巧在所有不同的体系结构中更为普遍。

在大多数现代架构中,CAS指令以某种形式提供,但每种架构中都会有不同的实现。

有趣的引自Brian Goetz(据说)

  

操作的相对速度在很大程度上不是问题。相关的是基于锁的算法和非阻塞算法之间的可扩展性差异。如果您在1或2核心系统上运行,请不要再考虑这些事情了。

     

非阻塞算法通常可以更好地扩展,因为它们比基于锁的算法具有更短的“关键部分”。

答案 1 :(得分:1)

请注意,CAS不一定要访问内存。

大多数现代架构都实现了像MESI这样的缓存一致性协议,如果只有一个线程同时访问数据,则允许CPU执行快捷方式。在这种情况下,与传统的,不同步的内存访问相比,开销非常低。

然而,当对相同的值进行大量并发更改时,缓存确实毫无价值,并且所有操作都需要直接访问主内存。在这种情况下,同步不同CPU缓存和内存访问序列化的开销可能会导致性能显着下降(这也称为缓存乒乓),这可能与您遇到的情况一样糟甚甚至更糟基于锁的方法。

所以,不要简单地假设如果你切换到原子,你的所有问题都会消失。原子的最大优点是无锁(有人总能取得进步)或无等待(每个人都经过一定数量的步骤)实现的进度保证。但是,这通常与原始性能正交:无等待解决方案可能比基于锁的解决方案慢得多,但在某些情况下,您愿意接受这一点以获得进度保证。

答案 2 :(得分:0)

Compare and swap(又名CAS)(check then act模式的一部分),它是一种 atomic 算法,可以更改一个值在多线程环境中。

该算法通常采用树形参数:

  1. V-价值地址
  2. A-旧值(最后知道的值)
  3. B-新值

,由树形步骤组成:

  1. 检查,如果旧值(A)等于地址(V)中的值
  2. 如果是-将新值(B)放入地址(V)(交换旧值并添加新值)
  3. 如果否-表示失败

如果发生故障,请更新旧值(A)并重复

当然,您可以使用synchronized [About]监视器来实现它,但是从Java 5您可以使用java.util.concurrent.atomic软件包的优点,该软件包使用更快,更高效的CPU操作。例如:

AtomicBooleanAtomicIntegerAtomicLong ...通过compareAndSet()方法

在后台,它使用sun.misc.Unsafe和本机sun.misc.Unsafe.compareAndSwapInt()方法。

Unsafe支持CAS,内存分配,创建实例而无需调用构造函数...