Research aside, I don't really know of anyone or any company using hardware-provided transactional memory in the industry. Yes, software transactional memory is frequently used by Clojure and Haskell people, but hardware TM? I've only ever read about Intel TSX in the manual. Can someone provide some examples of that being used in the industry?
Correct, for people that play the emulator I mentioned above and don't care about losing data sure to the TSX bug there's a tool called UBU that allows you to step back on the microcode revision on the motherboard bios update to reenable TSX again, then upon booting you need to delete mcupdategenuineintel.dll(some like that) which is a later soft patch to disable TSX in the OS, and you end up with TSX enabled again on older CPUs.
Some variants of lock elison in glibc use Intel TSX. I don't have a full overview of how locking is implemented for different x86 generations in there, but TSX is definitely used in some cases.
Also, some commercial database engines seem to make use of TSX for optimization.
don't know if fundamental issues with transactional memory (right off the top of my head):
- interaction with non-transactional code including access to shared data from outside of transactions
- exception handling, and propagating exception info
- how would interaction happen with code that cannot fit this (transactional) model ?
- how to ensure that system makes progress in presence of conflicts (livelock)
- <this space is for rent :o)>
there are 'soft' issues as well f.e. debugging aborted transactions, where execution paths might not be deterministic and or repeatable etc. further torpedoes productivity arguments...
This all works with lock elision with TSX and similar HTM technologies.
- interaction with non-transactional code including access to shared data from outside of transactions
The non transactional code just uses the lock, or it uses other suitable semantics when non locking code interacts with locking code (e.g. rules about read only vs writable with technologies like RCU). Any violations lead to aborts due to the cache coherency, and degrade to what would happen without transactions.
- exception handling, and propagating exception info
Just aborts the transaction, and then it works normally.
- how would interaction happen with code that cannot fit this (transactional) model ?
See above.
- how to ensure that system makes progress in presence of conflicts (livelock)
HTM is generally (with a few exceptions) best effort, so always needs to have a valid non transactional fall back path. Usually the fall back path
However in practice this all rarely happens because real systems have enough noise, it's more a theoretical problem.
- debugging aborted transactions
You profile them. TSX has extensive facilities for that. I wrote about it here
There's also Processor Trace in newer Intel CPUs which makes it quite easy to see what's going inside transactions.
Some of the issues you're describing happen with a full software transactional memory model, not a lock elision model, where you don't want to rely on locks. But even those can be mostly solved with straight forward techniques, by falling back to global locks.
However most usage of HTM is not a full transactional model, but just lock elision, which doesn't really have any of these problems you're listing.
The main use of hardware TM at the moment I believe is lock elision--your threading library can try to use a transaction, and only resort to a lock if the transaction aborts.
Hardware TM I think jumped the gun for implementation. On its own, it has a simple memory model, but when you try to interact it with the usual memory model, the interactions are difficult and complicated (the paper here shows that ARM's proposal for HTM makes lock elision impossible). There is also the annoyance that you have a maximum size of transaction region, but predicting your transaction region size and making your code handle different hardware region sizes are both tricky.
This sounds like a weird variant of double checked locking where the check-and-take is part of the transaction. That sounds like it breaks composability.
Can you provide s reference to the use of transactions that fall back to locks?
I'm not an expert on the x86 implementation, but my understanding of its implementation of hardware lock elision in this:
A lock in x86 is usually implemented as an atomic variable, with a read-modify-write to acquire it and another to release it, with appropriate memory barriers to squelch incorrect memory reordering. Hardware lock elision is described with a prefix to these read-modify-write instructions to indicate that it's a lock acquire instruction or a lock release instruction. What the hardware will do is first ignore the lock and execute the code as a transaction. If the transaction fails (which usually means another processor is writing to the same memory location), it restarts at the lock-acquire instruction and executes the regular locking code.
As you might imagine, this has all sorts of potentially crazy interactions with the regular memory model. The article that's linked here is a paper that built a full memory model of both the normal hardware/C++11 memory model and the transactional memory semantics, and then they use it to see if the hardware lock elision is actually correct. They found that the ARM model is broken, but the POWER and x86 hardware lock elision is correct.
I've used it in emulators to emulate loadlinked/storeconditional primitive archs a bit cleaner on x86. Those already look sort of like HTM if you squint hard enough. Even there, there's a lot of nuance to guarantee forward progress.
17 comments
[ 3.5 ms ] story [ 51.6 ms ] threadAlso, some commercial database engines seem to make use of TSX for optimization.
However in practice this all rarely happens because real systems have enough noise, it's more a theoretical problem.
You profile them. TSX has extensive facilities for that. I wrote about it herehttps://software.intel.com/en-us/blogs/2013/05/03/intelr-tra...
There's also Processor Trace in newer Intel CPUs which makes it quite easy to see what's going inside transactions.
Some of the issues you're describing happen with a full software transactional memory model, not a lock elision model, where you don't want to rely on locks. But even those can be mostly solved with straight forward techniques, by falling back to global locks.
However most usage of HTM is not a full transactional model, but just lock elision, which doesn't really have any of these problems you're listing.
Hardware TM I think jumped the gun for implementation. On its own, it has a simple memory model, but when you try to interact it with the usual memory model, the interactions are difficult and complicated (the paper here shows that ARM's proposal for HTM makes lock elision impossible). There is also the annoyance that you have a maximum size of transaction region, but predicting your transaction region size and making your code handle different hardware region sizes are both tricky.
Can you provide s reference to the use of transactions that fall back to locks?
A lock in x86 is usually implemented as an atomic variable, with a read-modify-write to acquire it and another to release it, with appropriate memory barriers to squelch incorrect memory reordering. Hardware lock elision is described with a prefix to these read-modify-write instructions to indicate that it's a lock acquire instruction or a lock release instruction. What the hardware will do is first ignore the lock and execute the code as a transaction. If the transaction fails (which usually means another processor is writing to the same memory location), it restarts at the lock-acquire instruction and executes the regular locking code.
As you might imagine, this has all sorts of potentially crazy interactions with the regular memory model. The article that's linked here is a paper that built a full memory model of both the normal hardware/C++11 memory model and the transactional memory semantics, and then they use it to see if the hardware lock elision is actually correct. They found that the ARM model is broken, but the POWER and x86 hardware lock elision is correct.