CPL 2016, week 13 Software transactional memory Oleg Batrashev - - PowerPoint PPT Presentation
CPL 2016, week 13 Software transactional memory Oleg Batrashev - - PowerPoint PPT Presentation
CPL 2016, week 13 Software transactional memory Oleg Batrashev Institute of Computer Science, Tartu, Estonia May 2, 2016 Overview Last weeks Clojure language core Immutable data structures Clojure simple state and design This week
Overview
Last weeks
◮ Clojure language core ◮ Immutable data structures ◮ Clojure simple state and design
This week
◮ Software transactional memory (STM)
Next weeks
◮ Agents in Clojure
Software transactional memory 68/83 Transactions -
Outline
Software transactional memory Transactions Software transactional memory
Software transactional memory 69/83 Transactions -
ACID properties
◮ long used with databases ◮ result is either abort or commit ◮ actions with
◮ atomicity – all or none effects of the action become visible ◮ consistency – data stays in consistent state after a transaction ◮ isolation – during its work the action is “completely” unaffected
by other threads
◮ durability – survives system failures
◮ Clojure STM transactions satisfy atomicity, consistency and
isolation
◮ durability
Software transactional memory 70/83 Transactions -
Isolation levels
Not as obvious as may seem. Concurrency with ANSI isolation levels
- 1. serializable – ideal case, as if run sequentially
- 2. repeatable read – new data may interfere (where clause in
SQL)
◮ phantom reads – second read returns more rows than first read
- 3. read committed – see the results of other transactions
◮ non-repeatable reads – read data changed by another commit
- 4. read uncommitted – see the changes in other transactions
◮ dirty reads – read data changed in another transaction
Software transactional memory 71/83 Transactions -
Isolation levels (2)
There is a criticism that ANSI levels
◮ too ambiguous ◮ does not cover all possible scenarios!
See A Critique of ANSI SQL Isolation Levels (1995)
Software transactional memory 72/83 Software transactional memory -
Outline
Software transactional memory Transactions Software transactional memory
Software transactional memory 73/83 Software transactional memory -
Classical problem
◮ transfer money from bankA to bankB (defn transfer [from to amount] (reset! from (- @from amount )) (reset! to (+ @to amount ))) ◮ Works without problems with single thread (def bankA (atom 20.0)) (def bankB (atom 10.0)) (transfer bankA bankB 4.0) (println @bankA) ; -> 16.0 (println @bankB) ; -> 14.0 ◮ deref/reset! is not atomic, so two threads may end up with
incorrect result
◮ classical Java solution uses locks
Software transactional memory 74/83 Software transactional memory -
Atomic is not enough
◮ make both operations atomic themselves (defn transfer2 [from to amount] (swap! from (fn [v] (- v amount ))) (swap! to (fn [v] (+ v amount )))) ◮ both swap! operations are atomic themselves ◮ however, if the second one fails (by any reason), the first one
has already removed money from the first account
◮ it is required to restore the original state
◮ there are more complex examples with many reads/writes
Software transactional memory 75/83 Software transactional memory -
Refs
◮ mutable entities that STM operates with ◮ must be accessed within a transaction (dosync) ◮ @/deref – read value of a ref
◮ inside transaction has repeatable read semantics ◮ in fact uses the value that was at the start of the transaction ◮ can do that using versions (explanation follows)
◮ ref-set – sets the value inside a transaction ◮ (alter ref update-fn & args...) – changes the value inside the
transaction
◮ other transactions see it only after this commits
◮ commute – special case where mutation time is not critical
◮ re-executed at the end of a transaction if needed
Software transactional memory 76/83 Software transactional memory -
STM Example
◮ banking example (def bankC (ref 20.0)) (def bankD (ref 10.0)) ◮ using deref and ref-set (defn transfer3 [from to amount] (dosync (ref -set from (- @from amount )) (ref -set to (+ @to amount )))) ◮ using alter (defn transfer4 [from to amount] (dosync (alter from (fn [v] (- v amount ))) (alter to (fn [v] (+ v amount )))))
Software transactional memory 77/83 Software transactional memory -
STM Diagram
Software transactional memory 78/83 Software transactional memory -
STM in Clojure
multiversion concurrency control (MVCC) in Clojure (implementation may differ from these semantics)
◮ every transaction has start time ◮ every ref has version – time of last commit
◮ read fails if current transaction start time < ref time,
transaction restarted unless
◮ copy has been made earlier on a write ◮ or there is appropriate version in the ref history queue (see
next slide)
◮ creates in-transaction copy for every ref written in transaction
◮ copies are saved to the ref on commit, if their versions (times)
has not been changed since the start of the transaction
Software transactional memory 79/83 Software transactional memory -
Ref history queue
◮ every ref has history queue of previous ref values (ref -history -count rf)
◮ initially history is not maintained (count=0), even when
written
◮ history queue count is increased if there is failed read (see
previous slide)
◮ no actual value is yet stored at this point ◮ value is stored on any following commit
◮ idea: transaction need not be restarted if there is the version
in the history that was at the start of the transaction
◮ ref-min-history, ref-max-history (see ref documentation)
Software transactional memory 80/83 Software transactional memory -
Write-skew
◮ value used in a transaction that is never written, but may be
modified at the end of the transaction
◮ book example: daylight parameter that defines how much
damage is inflicted in the battle
◮ my example: max energy available <= sum of consumed
energies
◮ if max energy is rewritten while transaction changes one of
consumed energies
◮ transaction uses historical value of the max energy
◮ Clojure solution: ensure command – as (ref-set a @a) but more
efficient
◮ does not cause other transactions to fail
Software transactional memory 81/83 Software transactional memory -
Livelock problem
◮ one long transaction ◮ many short transactions that modify a value read or written by
the long one
◮ read fails because history queue needs to grow very long before
long transaction may succeed
◮ write fails because confilcted value always overwritten when
long transaction finishes, so it has to restart
Guideline:
◮ try to reduce number of refs with potential conflict ◮ try to keep transactions short
Software transactional memory 82/83 Software transactional memory -
Summary
◮ Use two levels in your program:
- 1. immutable state of objects
- 2. stored in mutable refs that are modified in transactions
◮ for example
- 1. game state (field state, player states) is stored in immutable
structures
- 2. game itself is stored in mutable ref that may be modified by