I participated in the hobbyist development of the BitTorrent client in Haskell (named conjure). It uses STM quite heavily to coordinate different threads (1 per peer + 1 for storage management + 1 for overall management).
Benefits: less locks, readable code.
Speed was not an issue, at least not due to STM usage.
We use it pretty routinely for high concurrency apps at Galois (in Haskell). It works, its used widely in the Haskell world, and it doesn't deadlock (though of course you can have too much contention). Sometimes we rewrite things to use MVars, if we've got the design right -- as they're faster.
Just use it. It's no big deal. As far as I'm concerned, STM in Haskell is "solved". There's no further work to do. So we use it.
The article "Software Transactional Memory: Why is it Only a Research Toy?" (Călin Caşcaval et al., Communications of the ACM, Nov. 2008), fails to look at the Haskell implementation, which is a really big omission. The problem for STM, as the article points out, is that implementations must chose between either making all variable accesses transactional unless the compiler can prove them safe (which kills performance) or letting the programmer indicate which ones are to be transactional (which kills simplicity and reliability). However the Haskell implementation uses the purity of Haskell to avoid the need to make most variable uses transactional, while the type system provides a simple model together with effective enforcement for the transactional mutation operations. Thus a Haskell program can use STM for those variables that are truly shared between threads whilst guaranteeing that non-transactional memory use is kept safe.
We, factis research GmbH, are using Haskell STM with GHC in production. Our server receives a stream of messages about new and modified "objects" from a clincal "data server", it transforms this event stream on the fly (by generating new objects, modifying objects, aggregating things, etc) and calculates which of these new objects should be synchronized to connected iPads. It also receives form inputs from iPads which are processed, merged with the "main stream" and also synchronized to the other iPads. We're using STM for all channels and mutable data structures that need to be shared between threads. Threads are very lightweight in Haskell so we can have lots of them without impacting performance (at the moment 5 per iPad connection). Building a large application is always a challenge and there were many lessons to be learned but we never had any problems with STM. It always worked as you'd naively expect. We had to do some serious performance tuning but STM was never a problem. (80% of the time we were trying to reduce short-lived allocations and overall memory usage.)
STM is one area where Haskell and the GHC runtime really shines. It's not just an experiment and not for toy programs only.
We're building a different component of our clincal system in Scala and have been using Actors so far, but we're really missing STM. If anybody has experience of what it's like to use one of the Scala STM implementations in production I'd love to hear from you. :-)
We have implemented our entire system (in-memory database and runtime) on top of our own STM implementation in C. Prior to this, we had some log and lock based mechanism to deal with concurrency, but this was a pain to maintain. We are very happy with STM since we can treat every operation the same way. Almost all locks could be removed. We use STM now for almost anything at any size, we even have a memory manager implement on top.
The performance is fine but to speed things up we now developed a custom operating system in collaboration with ETH Zurich. The system natively supports transactional memory.
But there are some challenges caused by STM as well. Especially with larger transactions and hotspots that cause unnecessary transaction conflicts. If for example two transactions put an item into a linked list, an unnecessary conflict will occur that could have been avoided using a lock free data structure.
I'm currently using Akka in some PGAS systems research. Akka is a Scala library for developing scalable concurrent systems using Actors, STM, and built-in fault tolerance capabilities modeled after Erlang's "Let It Fail/Crash/Crater/ROFL" philosophy. Akka's STM implementation is supposedly built around a Scala port of Clojure's STM implementation. An overview of Akka's STM module can be found here.
发布评论
评论(6)
我参与了 Haskell 中 BitTorrent 客户端的爱好者开发(名为 conjure)。 它大量使用 STM 来协调不同的线程(每个对等 1 个线程 + 1 个用于存储管理 + 1 个用于整体管理)。
好处:锁少,代码可读。
速度不是问题,至少不是因为 STM 的使用。
希望这可以帮助
I participated in the hobbyist development of the BitTorrent client in Haskell (named conjure). It uses STM quite heavily to coordinate different threads (1 per peer + 1 for storage management + 1 for overall management).
Benefits: less locks, readable code.
Speed was not an issue, at least not due to STM usage.
Hope this helps
我们在 Galois(在 Haskell 中)的高并发应用程序中经常使用它。 它有效,在 Haskell 世界中广泛使用,并且不会陷入僵局(当然你可能会有太多争用)。 有时,如果我们的设计正确的话,我们会重写一些东西来使用 MVar,因为它们更快。
只需使用它即可。 没什么大不了的。 就我而言,Haskell 中的 STM 已经“解决”了。 没有进一步的工作要做。 所以我们使用它。
We use it pretty routinely for high concurrency apps at Galois (in Haskell). It works, its used widely in the Haskell world, and it doesn't deadlock (though of course you can have too much contention). Sometimes we rewrite things to use MVars, if we've got the design right -- as they're faster.
Just use it. It's no big deal. As far as I'm concerned, STM in Haskell is "solved". There's no further work to do. So we use it.
文章“软件事务内存:为什么它只是一个研究玩具?”(Călin Caşcaval 等人,Communications of the ACM,2008 年 11 月),没有考虑 Haskell 的实现,这是一个很大的遗漏。 正如文章所指出的,STM 的问题在于,实现必须选择是要么使所有变量访问成为事务性的,除非编译器可以证明它们是安全的(这会降低性能),要么让程序员指示哪些变量访问是事务性的(这会降低简单性)和可靠性)。 然而,Haskell 实现使用 Haskell 的纯粹性来避免大多数变量使用事务性的需要,而类型系统提供了一个简单的模型以及事务性突变操作的有效执行。 因此,Haskell 程序可以将 STM 用于那些在线程之间真正共享的变量,同时保证非事务性内存使用的安全。
The article "Software Transactional Memory: Why is it Only a Research Toy?" (Călin Caşcaval et al., Communications of the ACM, Nov. 2008), fails to look at the Haskell implementation, which is a really big omission. The problem for STM, as the article points out, is that implementations must chose between either making all variable accesses transactional unless the compiler can prove them safe (which kills performance) or letting the programmer indicate which ones are to be transactional (which kills simplicity and reliability). However the Haskell implementation uses the purity of Haskell to avoid the need to make most variable uses transactional, while the type system provides a simple model together with effective enforcement for the transactional mutation operations. Thus a Haskell program can use STM for those variables that are truly shared between threads whilst guaranteeing that non-transactional memory use is kept safe.
我们 factis Research GmbH 在生产中使用 Haskell STM 和 GHC。 我们的服务器从临床“数据服务器”接收有关新的和修改的“对象”的消息流,它动态地转换此事件流(通过生成新对象、修改对象、聚合事物等)并计算这些新对象中的哪些对象应同步到连接的 iPad。 它还接收来自 iPad 的表单输入,这些表单输入经过处理、与“主流”合并并同步到其他 iPad。 我们将 STM 用于需要在线程之间共享的所有通道和可变数据结构。 Haskell 中的线程非常轻量,因此我们可以拥有很多线程而不影响性能(目前每个 iPad 连接有 5 个线程)。 构建大型应用程序始终是一个挑战,有很多经验教训需要学习,但我们在 STM 方面从未遇到过任何问题。 它总是像你天真地期望的那样工作。 我们必须进行一些认真的性能调整,但 STM 从来都不是问题。 (80% 的时间我们都在尝试减少短期分配和整体内存使用。)
STM 是 Haskell 和 GHC 运行时真正大放异彩的领域之一。 这不仅仅是一个实验,也不仅仅是玩具程序。
我们正在 Scala 中构建临床系统的不同组件,并且到目前为止一直在使用 Actor,但我们确实缺少 STM。 如果有人有在生产中使用 Scala STM 实现之一的经验,我很乐意听取您的意见。 :-)
We, factis research GmbH, are using Haskell STM with GHC in production. Our server receives a stream of messages about new and modified "objects" from a clincal "data server", it transforms this event stream on the fly (by generating new objects, modifying objects, aggregating things, etc) and calculates which of these new objects should be synchronized to connected iPads. It also receives form inputs from iPads which are processed, merged with the "main stream" and also synchronized to the other iPads. We're using STM for all channels and mutable data structures that need to be shared between threads. Threads are very lightweight in Haskell so we can have lots of them without impacting performance (at the moment 5 per iPad connection). Building a large application is always a challenge and there were many lessons to be learned but we never had any problems with STM. It always worked as you'd naively expect. We had to do some serious performance tuning but STM was never a problem. (80% of the time we were trying to reduce short-lived allocations and overall memory usage.)
STM is one area where Haskell and the GHC runtime really shines. It's not just an experiment and not for toy programs only.
We're building a different component of our clincal system in Scala and have been using Actors so far, but we're really missing STM. If anybody has experience of what it's like to use one of the Scala STM implementations in production I'd love to hear from you. :-)
我们已经在自己的基础上实现了整个系统(内存数据库和运行时)用 C 语言实现 STM。在此之前,我们有一些基于日志和锁的机制来处理并发,但这维护起来很痛苦。 我们对 STM 非常满意,因为我们可以以同样的方式对待每一次手术。 几乎所有的锁都可以拆除。 我们现在将 STM 用于几乎任何大小的任何东西,我们甚至在顶部实现了内存管理器。
性能很好,但为了加快速度,我们现在与苏黎世联邦理工学院合作开发了一个自定义操作系统 。 该系统本身支持事务内存。
但 STM 也带来了一些挑战。 尤其是较大的交易和热点会导致不必要的交易冲突。 例如,如果两个事务将一个项目放入链表中,则会发生不必要的冲突,而使用无锁数据结构可以避免这种冲突。
We have implemented our entire system (in-memory database and runtime) on top of our own STM implementation in C. Prior to this, we had some log and lock based mechanism to deal with concurrency, but this was a pain to maintain. We are very happy with STM since we can treat every operation the same way. Almost all locks could be removed. We use STM now for almost anything at any size, we even have a memory manager implement on top.
The performance is fine but to speed things up we now developed a custom operating system in collaboration with ETH Zurich. The system natively supports transactional memory.
But there are some challenges caused by STM as well. Especially with larger transactions and hotspots that cause unnecessary transaction conflicts. If for example two transactions put an item into a linked list, an unnecessary conflict will occur that could have been avoided using a lock free data structure.
我目前正在一些 PGAS 系统研究中使用 Akka。 Akka 是一个 Scala 库,用于使用 Actor、STM 和模仿 Erlang 的“内置容错功能”来开发可扩展的并发系统让它失败/崩溃/陨石坑/ROFL”的理念。 Akka 的 STM 实现据说是围绕 Clojure 的 STM 实现的 Scala 端口构建的。 Akka 的 STM 模块概述可以在此处找到。
I'm currently using Akka in some PGAS systems research. Akka is a Scala library for developing scalable concurrent systems using Actors, STM, and built-in fault tolerance capabilities modeled after Erlang's "Let It Fail/Crash/Crater/ROFL" philosophy. Akka's STM implementation is supposedly built around a Scala port of Clojure's STM implementation. An overview of Akka's STM module can be found here.