3 ms·
Ask YC: A simpler STM implementation?
I'm pondering an STM (http://en.wikipedia.org/wiki/Software_transactional_memory) implementation in C#. For me, the main reason to use STM is not because I think locking is complicated, but because of the speed gains. With that said, I find the current STM implementations (in .NET, at least) cumbersome and slow, because they involve cloning and a proxy object for every single object.
So I have thought of several potential improvements to traditional STM, which bring it closer to optimistic locking, and wanted to hear your opinion:
1) Lock on race conditions.
Go ahead and execute the transaction, but if you detect a conflict, acquire a lock on the relevant object and execute the transaction again. Seems like a better decision, with a guaranteed worst execution time, than implementing some kind of throttling.
2) Non-transactional objects.
The idea is to have an STM method like so:
void STMExecute<T>(T obj, Func<T, bool> transaction, Func<T, bool> failsafeTransaction)
(FYI in C#, Func<T1, ..., Tn, TR> is a lambda with parameters of types T1..n and return type TR.)
STMExecute would keep track of the generation counter for obj, run the transaction lambda, and if it fails, or there is a conflict, acquire a lock on obj, and run failsafeTransaction.
For example, in a banking system, transaction would increment the account (obj)'s balance by 100, and failsafeTransaction would recompute the balance by going through the history of withdrawals and deposits for the account.
3) No side effect functions
STMExecute would be changed to
void STMExecute<T>(ref T obj, Func<T, T> transaction)
transaction would return a new T instance based on the original object, without changing the original object. True, there is some cloning involved, but it works without proxy objects.
A potential issue is that C# doesn't offer a way to enforce transactions have no side effects. This can be done by making immutable types, though.
4) What is a good benchmark?
What's a good, realistic way to test the performance of STM, compared to locks? The most obvious way - run several threads like so:
while (true) {
STMExecute(ref var, x => x + 1);
}
would always show locks as the winner, as STMExecute will default to locks when a conflict occurs. This scenario is unrealistic, though. Any better ideas?
- cx01 18y ago"For me, the main reason to use STM is not because I think locking is complicated, but because of the speed gains." I'm rather confident that STM is a lot slower than locking. Wasn't the main idea of STM to simplify coding while sacrificing some performance?
- andr 18y agoI know, but I'm trying to get the best parts of STM to actually get an improvement in performance.
- cx01 18y agoI don't think that's possible, but would be happy if proven wrong. I just downloaded the STM implementation and it seems to include some benchmarks. So that could be at least an answer to your question 4.
- deleted 18y ago[deleted]
- andr 18y agoSorry, that's Software Transactional Memory. http://en.wikipedia.org/wiki/Software_transactional_memory http://en.wikipedia.org/wiki/Software_transactional_memory