【问题标题】:What is the difference between the 'Compare And Swap' and 'Compare And Set' operations?\'Compare And Swap\' 和 \'Compare And Set\' 操作有什么区别?
【发布时间】:2022-09-25 03:43:54
【问题描述】:

我试图理解“比较和交换”操作,简称为 CAS。我发现它有一个名为“比较和设置”的变体。它们的工作方式相同,但回报不同。 \'Compare And Swap\' 返回一个值,但 \'Compare And Set\' 返回一个布尔值。

我的问题是他们是否在低级别使用相同的比较和交换(CMPXCHG for x86)指令。它们都是由 Java 中的原子类实现的吗?

  • 使用比较和交换很容易模拟比较和设置,但反之则不然。怀疑Java为了可移植性而省略了比较和交换,但它是用x86上的CMPXCHG实现的(这是最明显的方法)。
  • BTS 是 x86 上的测试和设置指令,但它仅适用于位。它确实适用于原子功能的 LOCK 前缀。

标签: java algorithm assembly compare-and-swap


【解决方案1】:

是的,它是一个包装器,它公开了 x86 lock cmpxchg 或其他 ISA 上的等效 compare-and-swap 指令/序列的功能。但是 Java 的旧的compareAndSet API 只返回布尔成功,而不是失败的旧值,所以有些事情它不能完全做到。

最近的一个问题,Java 8 impl on Compare And Exchange (Not Compare and Set!)是关于在 Java compareAndSet 方面模拟 Java17 compareAndExchange(返回旧值) - 它不能精确地完成。您可以在交换时间附近加载一个值,但即使您的 CAS 失败,它也可能最终与您的 CAS 的“预期”arg 相同。但是,如果您将布尔值和读取的值分开保存,那么对于大多数算法来说都可以。

对于您确实想要旧值的情况,这种情况就像GNU C's old __sync_bool_compare_and_swap__sync_val_...。后者更强大:你能够通过自己比较返回值从val 版本中获取成功/失败。因此,Java 仅提供从 Java 8 到 Java 17 中功能较弱的一种,这有点令人失望,尽管它是许多算法更可能使用的一种。

(GNU C 后来添加了 __atomic 内置函数,它与 compare_exchange_weak 的 C++11 API 匹配,带有 bool 返回值和第一个 arg 引用,在 CAS 失败时更新。所以你得到一个或两个,取决于你的输出麻烦实际使用。)

还有相关的:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 2019-09-27
    • 2022-12-27
    • 2011-07-29
    相关资源
    最近更新 更多