Transactional Memory in GCC

Background

Transactional memory is intended to make programming with threads simpler, in particular synchronizing access to data shared between several threads using transactions. As with databases, a transaction is a unit of work that either completes in its entirety or has no effect at all (i.e., transactions execute atomically). Further, transactions are isolated from each other such that each transaction sees a consistent view of memory.

Currently, transactions are only supported in C++ and C in the form of transaction statements, transaction expressions, and function transactions. In the following example, both a and b will be read and the difference will be written to c , all atomically and isolated from other transactions:

__transaction_atomic { c = a - b; }

Therefore, another thread can use the following code to concurrently update b without ever causing c to hold a negative value (and without having to use other synchronization constructs such as locks or C++11 atomics):

__transaction_atomic { if (a > b) b++; }

The precise semantics of transactions are defined in terms of the C++11/C1X memory model (see below for a link to the specification). Roughly, transactions provide synchronization guarantees that are similar to what would be guaranteed when using a single global lock as a guard for all transactions. Note that like other synchronization constructs in C/C++, transactions rely on a data-race-free program (e.g., a nontransactional write that is concurrent with a transactional read to the same memory location is a data race).

The implementation of transactional memory is transparent to the program and most of it resides in a runtime library (libitm in GCC). Transactions thus always provide the same guarantees, even though performance at runtime might be different depending on the implementation that is being used. In general, implementations come in two forms: a Software Transactional Memory (STM) system uses locks or other standard atomic instructions to do its job. A Hardware Transactional Memory (HTM) system uses multi-word synchronization operations of the CPU to implement the requirements of the transaction directly (e.g., see the Rock processor). Because most HTM systems are likely to be best effort facilities (i.e., not all transactions can be executed using HTM), practical TM implementations that incorporate HTM also have a STM component and are thus termed Hybrid Transactional Memory systems.

Status

The transactional memory work has been merged into trunk and will be available in GCC 4.7. The support is experimental. In particular, this also means that several parts of the implementation are not yet optimized. If you observe performance that is lower than expected, you should not assume that transactional memory is inherently slow; instead, please just file a bug.

A part of the work on this branch has been done as part of the Velox project.

Language Extensions

The specification of the language extensions that are implemented in GCC can be found here. Another paper provide more background information about Transactional Memory and this specification.

Library ABI

Intel-TM-ABI-1_1_20060506.pdf

The above document is a work-in-progress to define a flexible TM runtime library ABI that can be used for both pure STM, HTM and Hybrid TM implementations. The ABI that GCC uses has a few differences to what is specified in this document, which are enumerated in the libitm documentation.