【问题标题】:software transaction memory(STM) vs compare and swap(CAS)软件事务存储器(STM)与比较和交换(CAS)
【发布时间】:2018-02-01 22:38:38
【问题描述】:

我一直在通过 STM 在没有传统锁的情况下进行并发,它解释了在将共享值永久提交到共享值之前比较共享值。

CAS 也做同样的事情。线程获取他们想要更改的数据的副本并应用他们的更改,乐观的假设是在此期间没有其他线程对共享内存进行更改。当这个乐观的假设成立时,线程只是设法更新共享内存而没有锁定。当这个假设不成立时,工作就被浪费了,但仍然没有应用锁定。

CAS和STM是互用的还是这两者有什么区别??

【问题讨论】:

  • 你的想法跨越了几个抽象层。 CAS 是用于并发控制的极低级原语。可以用CAS来实现传统的锁,这是一种更高层次的机制,也可以用传统的锁来实现软件事务内存,它是一种更高级的机制。

标签: multithreading concurrency


【解决方案1】:

CAS 仅适用于单个位置,而 STM 通常允许更新稀疏数据结构。这两个都有更高级别的抽象。 简而言之,CAS 在不允许此类操作的架构上模拟原子读取-修改-写入循环。 RMW 不能很好地扩展。模拟涉及三个步骤:声明缓存行的所有权,确定要写入该行的新数据,如果所有权声明仍然有效,则重写位置。因为操作是有条件的,所以它可能会失败,因为比较失败,或者缓存行在操作期间被撤销。

STM 在此基础上支持 N 个缓存行。现代 cpus 中的机制有点狡猾,但可以这样处理:

while (1) {
     setjmp(current_pc).
     update locations 1 thru N.
     if (commit()) {
          break;
     }
}

除非所有位置的提交都成功,否则更新在此核心之外不可见。因此,您可以遍历一个链表,反转链表中的指针,但所有更改的节点只会出现在您的缓存中,直到提交,此时对于任何观察者,整个链表都会自动更改。在 setjmp 和 commit 之间的任何时间点,任何会导致事务失败的事情都会将 cpu 倒回到 setjmp 点。此倒带将放弃所有更新。

正如您所注意到的,这样做是有代价的,即我可能不得不多次重复 while 循环。在实践中情况更糟。

N,要更新的位置数量不能超过私有缓存的大小;这个魔法只有通过让缓存拒绝发布更新直到事务完成才有效,因此需要将数据存储在这个缓存中。

缓存通常具有有限的关联性,例如 SkyLake L1 缓存是 8 路关联的。在上面的链表中,假设有 9 个节点碰巧在一个缓存桶上发生碰撞;交易注定要失败,因为没有地方可以存储第 9 个条目。外层 while 循环无济于事;除非您提供不使用 STM 机制的列表更新的第二个实现,否则您将陷入循环。现在你有两个问题。

假设在您的事务中间发生中断,并开始一个新事务。它们不筑巢。

STM 的硬件实现作为一种通用机制还有待改进;然而,作为内核内部的单点解决方案,它有很大的前景。

【讨论】:

  • 所以 STM 是一个整体的架构,将事件视为事务,而 CAS 是获得 STM 的机制??
猜你喜欢
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 2021-01-09
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 2013-10-27
  • 2012-01-15
相关资源
最近更新 更多