软件事务存储器(STM)与比较和交换(CAS)

时间:2018-01-31 19:37:10

标签: multithreading concurrency

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

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

CAS和STM是否采用交互式方式或两者之间的区别是什么?

1 个答案:

答案 0 :(得分:1)

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

STM以此为基础来支持N个缓存行。现代cpu中的机制有点狡猾,但是可以这样做:

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 while循环无济于事;除非您提供不使用STM机制的列表更新的第二个实现,否则您将陷入循环。现在你有两个问题。

假设在事务中间发生中断,并启动新事务。他们没有窝。

STM的硬件实现留下了一些需要作为一般机制;然而,作为内核内部的一个重点解决方案,它有很大的希望。