Concurrency · transactional memory · STM

Transactional memory after the hype

Transactional memory once looked like a cleaner route out of lock-heavy concurrent code. In practice, hardware transactional memory remained narrow and fragile, while software transactional memory survived in a smaller but more usable role inside certain languages and runtimes.

The core criticism

The main criticism of transactional memory is familiar: it promised a form of lock elision that might accelerate read-heavy code, but real programs often run into transaction-size limits, conflict-heavy access patterns, and incidental writes such as counters or metrics. Once those effects appear, the optimistic path can collapse into repeated aborts and fallback behavior.

The practical criticism was not that transactional memory is impossible, but that it is easy to exceed the conditions under which it works well.

What transactional memory was supposed to offer

The original transactional memory idea, introduced by Maurice Herlihy and J. Eliot B. Moss, was to let code mark a sequence of reads and writes as a transaction that either commits atomically or rolls back. That promised a cleaner alternative to fine-grained locks for some concurrent data structures. A few years later, Nir Shavit and Dan Touitou extended the idea into software transactional memory, showing that similar semantics could be provided in software rather than by the processor itself.

At a high level, the appeal was straightforward: write concurrent code in larger logical units, avoid some manual lock choreography, and let the system detect conflicts.

Why hardware transactional memory never became a default answer

Intel's Transactional Synchronization Extensions, or TSX, are the best-known mainstream x86 example of hardware transactional memory. TSX provides two interfaces: Hardware Lock Elision (HLE) and Restricted Transactional Memory (RTM). Intel's own documentation also makes clear why the model is delicate: transactions can abort when another logical processor writes to a cache line in the transaction's read set, when the transaction exceeds available buffering space, or for other microarchitectural reasons.

That means the success of HTM depends heavily on workload shape. Performance can look good when the transaction footprint is small and conflicts are rare, but it degrades quickly when the memory footprint grows, when sharing is more intense than expected, or when fallback paths are frequently exercised.

Security problems made the story worse. Intel's TSX Asynchronous Abort guidance documents the TAA vulnerability and the mitigations around it. In practice, TSX has remained present in documentation and tooling, but its operational value has been reduced by both fragile workload behavior and the cost of security mitigations.

What the studies show

The literature does not say that HTM is useless. It says that HTM is conditional. Early evaluations of Intel TSX showed measurable gains on selected workloads, but the same body of work also emphasized limits imposed by conflicts, transaction capacity, and sensitivity to data layout and access patterns.

The common pattern across these studies is that HTM can be useful when the workload is cooperative. It is much less convincing as a transparent accelerator for arbitrary lock-based code.

What about software transactional memory?

Software transactional memory, or STM, is the part that persisted more cleanly. STM does not rely on special CPU instructions. Instead, a runtime tracks transactional reads and writes in software and retries or rejects transactions when conflicts occur.

STM is not free. It adds runtime overhead, still suffers under high contention, and is awkward around side effects that cannot be repeated safely. But compared with HTM, STM is more predictable and more portable because it does not depend on narrow hardware conditions.

That is why STM found a durable place in language ecosystems, even if it never displaced other concurrency models such as actors, immutable data structures, message passing, lock-free algorithms, and simple atomics.

Clojure and STM

Clojure is a practical example of STM in a mainstream language. Its official documentation describes Refs as coordinated shared references managed by a software transactional memory system. Transactions are delimited by dosync, and coordinated updates happen with functions such as alter, ref-set, and commute.

(def account-a (ref 100))
(def account-b (ref 50))

(dosync
  (alter account-a - 10)
  (alter account-b + 10))

This is important because it separates two ideas that are often conflated:

They are related conceptually, but they occupy different layers and fail for different reasons.

What happened outside Intel?

On x86, AMD did not ship a mainstream equivalent to Intel TSX. There was an AMD proposal called Advanced Synchronization Facility, but it did not become a broadly deployed production counterpart.

Arm did define a Transactional Memory Extension, FEAT_TME. However, Arm's own documentation now marks that feature as withdrawn and keeps the guide available only for reference. That is a useful indicator of where the industry ended up: transactional memory remained technically interesting, but it did not become a stable cross-vendor baseline.

The practical conclusion

If lock contention is a serious problem, the best answer is often not to hope for a transparent transactional layer that rescues an otherwise poor sharing pattern. In many systems, better results come from changing the design itself: reduce shared mutable state, isolate ownership, communicate with messages, or use data structures and access patterns that avoid hot shared write locations.

In that sense, transactional memory did not disappear. It simply settled into a more limited role. HTM remained niche and conditional. STM survived as a useful abstraction in runtimes that can support it well.

Sources

  1. Maurice Herlihy and J. Eliot B. Moss, Transactional Memory: Architectural Support for Lock-Free Data Structures, 1993. ACM entry.
  2. Nir Shavit and Dan Touitou, Software Transactional Memory, 1995. PDF.
  3. Clojure documentation, Refs and Transactions. clojure.org/refs.
  4. Clojure documentation, Concurrent Programming. clojure.org/about/concurrent_programming.
  5. Intel, Intel TSX Asynchronous Abort. Intel documentation.
  6. Intel, TSX Asynchronous Abort / CVE-2019-11135 / INTEL-SA-00270. Intel advisory.
  7. Rajwar M. Yoo et al., Performance Evaluation of Intel Transactional Synchronization Extensions for High-Performance Computing, SC13. PDF.
  8. Viktor Leis, Alfons Kemper, and Thomas Neumann, Exploiting Hardware Transactional Memory in Main-Memory Databases, 2014. PDF.
  9. Arm, Overview of Arm Transactional Memory Extension. Arm documentation.
  10. Arm, Overview of Arm Transactional Memory Extension guide. Arm documentation landing page.