Any Real-World Experience Using Software Transactional Memory?
最近人们对STM(软件事务性内存)框架和语言扩展的兴趣似乎越来越浓厚。Clojure尤其有一个优秀的实现,它使用MVCC(多版本并发控制),而不是滚动提交日志。ghc haskell还具有非常优雅的stm monad,它还允许事务组合。最后,为了稍微吹响我自己的号角,我最近为scala实现了一个stm框架,它静态地强制引用限制。
所有这些都是有趣的实验,但它们似乎仅仅局限于那个领域(实验)。所以我的问题是:你们中有人在现实世界中见过或使用STM吗?如果是,为什么?它带来了什么样的好处?那表演呢?(在这一点上似乎有大量的冲突信息)您是否会再次使用stm,或者您更愿意使用一些其他并发抽象,如actors?
我参与了哈斯克尔BitTorrent客户机(名为"魔术师")的爱好者开发。它大量使用STM来协调不同的线程(每个对等机1个,存储管理1个,总体管理1个)。
优点:锁更少,代码可读。
速度不是问题,至少不是因为stm的使用。
希望这有帮助
我们经常在Galois(Haskell)使用它来实现高并发性应用程序。它可以工作,在haskell世界中广泛使用,并且不会死锁(当然,您可能会有太多的争用)。有时,如果设计正确,我们会重写一些东西来使用MVAR,因为它们速度更快。
就用它吧。没什么大不了的。就我而言,Haskell的stm是"解决"的。没有进一步的工作要做。所以我们使用它。
文章"软件交易记忆:为什么它只是一个研究玩具?"无法查看haskell实现,这是一个非常大的遗漏。正如本文所指出的,STM的问题在于,实现必须在使所有变量访问成为事务性访问之间进行选择,除非编译器能够证明这些访问是安全的(这会降低性能),或者让程序员指出哪些访问是事务性的(这会降低简单性和可靠性)。然而,haskell实现使用haskell的纯度来避免大多数变量使用事务性变量的需要,而类型系统提供了一个简单的模型以及对事务性突变操作的有效执行。因此,haskell程序可以对那些在线程之间真正共享的变量使用stm,同时保证非事务性内存的使用是安全的。
我们,Factis Research GmbH,正在生产中使用Haskell STM和GHC。我们的服务器从关键的"数据服务器"接收有关新的和修改过的"对象"的消息流,它动态地转换此事件流(通过生成新对象、修改对象、聚合对象等),并计算哪些新对象应与连接的iPad同步。它还接收来自ipad的表单输入,这些输入被处理、与"主流"合并并与其他ipad同步。我们正在为所有需要在线程之间共享的通道和可变数据结构使用STM。haskell的线程非常轻,因此我们可以在不影响性能的情况下拥有大量线程(目前每个ipad连接5个)。构建一个大型应用程序始终是一个挑战,需要吸取很多经验教训,但我们从未遇到过STM的任何问题。它总是像你天真地期望的那样工作。我们必须进行一些严重的性能调整,但stm从来都不是问题。(80%的时间我们试图减少短期分配和总体内存使用。)
STM是Haskell和GHC运行时真正闪耀的领域之一。这不仅仅是一个实验,而不仅仅是玩具程序。
我们在Scala构建了我们的临床系统的不同组成部分,到目前为止一直在使用演员,但是我们确实缺少了STM。如果任何人都有使用Scala STM实现的经验,我很乐意听取您的意见。-)
我们已经在C语言的stm实现之上实现了整个系统(内存数据库和运行时)。在此之前,我们有一些基于日志和锁的机制来处理并发性,但这是维护的一个难题。我们对STM非常满意,因为我们可以以同样的方式对待每一个操作。几乎所有的锁都可以拆下。我们现在对任何大小的东西都使用stm,我们甚至在上面有一个内存管理器实现。
性能很好,但为了加快速度,我们现在与苏黎世ETH合作开发了一个定制的操作系统。系统本身支持事务性内存。
但STM也带来了一些挑战。尤其是对于较大的事务和热点,它们会导致不必要的事务冲突。例如,如果两个事务将一个项目放到链表中,将发生一个不必要的冲突,这可能是使用无锁的数据结构避免的。
我目前正在一些PGAS系统研究中使用AKKA。AKKA是一个scala库,用于使用actors、stm和内置容错功能开发可扩展的并发系统,这些功能是仿照Erlang的"让它失败/崩溃/弹坑/ROFL"理念建模的。Akka的stm实现据说是围绕clojure的stm实现的scala端口构建的。AKKA的STM模块的概述可以在这里找到。