Nested Transactional Memory: Model and Preliminary

Nested Transactional Memory:
Model and Preliminary Architecture
Sketches
J. Eliot B. Moss
Antony L. Hosking
MOTIVATION
• Composition of Code
– Possible Solution - Grouping all nested actions within
their enclosing top-level action.
• Problems - Large monolithic actions increase the
volume of work that must be done if a
transaction needs to be rolled back.
– Possible Solutions – Closed Transactions.
– Allows each new portion of work to be attempted,
and possibly to fail, without necessarily aborting work
already accomplished
• Limit Concurreny
CLOSED NESTING
• Transactions
–
–
–
–
–
Top-level
Nested (child or sub-transactions)
Accumulate read and write sets
Data are not updated until a top-level transaction commits
Value Read.
• Conflicts
– At least one of the accesses is a write, and neither transaction is an ancestor
of the other.
• Commits
– Read and write sets are unioned with those of parent
– For top level transactions commits become permanent
• Aborts
– Read and Write Sets (and associated tentatively written values) Discarded.
OPEN NESTING
• Allows further increases in concurrency, by releasing
concrete resources earlier and applying conflict
detection (and roll back) at a higher level of abstraction
• Commit
– Discards its read set, and commit its writes at “top level.
– Removes the written data elements from the read and
write sets of all other transactions.
• Aborts
– Additional mechanisms handle recording of any necessary
compensating actions.
– Update a list of compensating actions held by the action’s
parent which are applied in cast of an abort.
NESTED EXECUTION MODEL
• Transactions
–
–
–
–
Have unique IDs.
Start live, may later commit or abort
Every non-zero transaction has a unique parent transaction
Running Transaction :
• A transaction with no (live) children, allowed to (attempt to) issue memory reads and
writes.
• Memory
– Map from memory locations memory values. Consists of different locations
each assigned a value.
• System States
– Includes all the “globally committed” memory state, plus memory state (read
and write sets) for each transaction currently live in the system.
– Is defined by a series of entries
– Each entry consisting of :
• Transaction,
• The memory location it writes to
• The value it contains
• A flag indicating whether the transaction has written to the location or not (read).
NESTED EXECUTION MODEL
• Read Set
– Consists of all entries for that transaction that
have flag to false
• Write Set
– Consists of all entries that have flag set to true.
• Loc Set
– Union of the above two
• Location Value
NESTED EXECUTION MODEL
• ALLOWED READ & WRITES
– A transaction can read a location of all other
entries for that location either belong to the
transaction itself, belong to one of its ancestors or
have write bit set to false.
– A transaction can write if all entries for that
location are either the transaction’s or one of its
ancestors.
NESTED EXECUTION MODEL
• EFFECTS of READS & WRITES
– State remains unchanged if an entry already
exists.
– If not new state consists of previous plus new
entry for the read carried out.
– Open nested reads – Set written bit if any
ancestor has it set. Used for global commit.
– Writes delete previous value for the entry and sets
written flag.
NESTED EXECUTION MODEL
• SEMANTICS OF COMMIT AND ABORT
– Allowed only if transaction has no children in state.
• COMMIT
– Open Nested Action: Updates the globally committed
state for words that it wrote and forces drops from all
transaction states of every word written. (Global
commit)
– Closed Action: Parent “inherits” its state
• ABORT
– Open Nested: Drop all entries associated with the
aborting transaction
H/W SKETCH 1: USING CACHE
• Hardware and Memory Tables
– Transaction Data Cache
• Transaction Parent Cache
• Overflow Summary Table
HW SKETCH-1
•
Creating Transaction
– Obtain a free Transaction Parent Cache entry and an unused transaction id.
•
Reading a Word.
–
–
–
–
Return Data if Cache contains Entry else
Check Overflow summary table.
Determine Parent and probe parent.
If there is no entry then
•
•
•
•
Obtain value from main memory.
Create two new entries: One for transaction 0 and one for current transaction.
Transaction 0 entry is marked valid and not dirty. Its reader count is set to 1.
The reading transaction’s entry is set to valid and dirty. Set Written and Ancestor written to 0, reader
count to 0 and obtained from to 0.
– If entry for ancestor exists
•
•
•
•
•
•
Pull it into cache.
Create new entry
Set new entry valid and dirty
Set Ancestor written to 1 if either Written or Ancestor written are 1 in the ancestor.
Set Written 1 if we just set Ancestor written and this is an open nested action.
Otherwise, increment Reader count of the ancestor’s entry
– Freeing Data Cache entries
– Determining Conflicts with Reads
HW SKETCH-1
• Writing a Word.
– Return Data if Cache contains Entry else
– If there is no entry then
• Obtain value from main memory.
• Create two new entries: One for transaction 0 and one for current transaction.
• Transaction 0 entry is marked valid and not dirty. Indicate current transaction as
writing transaction.
• The writing transaction’s entry is set to valid and dirty. Set Written to 1 and
Ancestor written to 0, reader count to 0 and obtained from to 0.
– If entry for ancestor exists
•
•
•
•
•
•
Pull it into cache.
Create new entry
Set new entry valid and dirty
Set data filed to value written
Set Ancestor writing transaction filed to current.
Current s obtained from to ancestor
– Find unwritten entry: Similar to second part of above.
– Determining Conflicts with Writes
HW SKETCH-1
• Aborting Transaction
– For each unwritten entry of the transaction, decrement
the Obtained-from transaction’s Reader count for this
entry.
– For each written entry of the transaction, set the
Obtained-from transaction’s Reader count to 0.
– Invalidate all entries of the aborting transaction
– If the transaction overflowed, process its overflowed
entries, updating Reader counts.
– If the parent cache entry is not dirty, then remove it
from the memory tables. Drop the transaction from the
parent cache.
HW SKETCH-1
• Committing a top-level transaction
• For each written entry, restore the transaction 0
entry (if necessary), and update its value.
• Mark the entry dirty and written, and set its
Reader count to 0.
• If the transaction has overflow entries, process
them then delete them.
• Delete the transaction’s parent cache entry,
including memory copy (if any).
• Committing a closed nested transaction: Merge
• Committing an open nested transaction: Drop
SKETCH 2: TAGGING ANCESTORS
• Ancestor bit, which indicates that this entry is
for an ancestor of the current transaction (or
the current transaction itself)
SKETCH 2: TAGGING ANCESTORS
•
Reading a word:
–
–
•
Writing a word:
–
•
For each entry of the committing transaction, if the parent has an entry, merge entries.
If the parent has no entry, just change the transaction id to that of the parent.
All Ancestor bits for the parent remain 1.
Committing an open nested transaction:
–
•
Drop unwritten entries of this transaction, and merge written ones with the transaction 0 entry.
Committing a closed nested transaction:
–
–
–
•
Simply invalidate all Transaction Data Cache entries for the transaction.
Committing a top-level transaction:
–
•
The write conflicts if there is any entry for the same word for a non-ancestor, easy to check with associative
matching on this address.
Aborting a transaction:
–
•
Conflict if there is any entry for the same address where a non-ancestor has written the word
Easy to check: address match, Ancestor bit 0,Written bit 1
drop all (non-0) transaction entries for Written data.
Switching transactions
–
Set all ancestor bit younger than common one to 0.
SKETCH 3: FAST COMMIT
• Watched Transaction
– Indicates a transaction to watch. If it commits,
then take special action. For abort clear field.
SKETCH 3: FAST COMMIT
•
Reading a word:
– A closed nested transaction is inherited by its parent on commit.
– For a read by an open nested action that results in an unwritten entry, set the Obtained-from
field to 0.
•
Writing a word:
– set theWatched transaction field of the youngest ancestor
– If the transaction is open nested, we set the Watched field of all ancestors
•
Committing a transaction:
– Broadcast across the cache the committing transaction’s id and its parent’s id.
– For open nested actions, drop unwritten entries and mutate written entries to transaction 0
– For closed nested actions, mutate unwritten entries to the parent, unless the parent matches
the Obtainedfrom field, in which case drop the entry.
– For written entries always mutate them to the parent.
•
Aborting a transaction:
– In addition to invalidating the transaction’s own entries, set to 0 any Watched transaction field
that matches the aborting transaction
LINEAR NESTING
• Disallow concurrency within a transaction, permitting
only a single leaf transaction for each top-level
transaction
• Live tree under each top-level transaction is linear,
consisting of a single branch
• Optimization: if an ancestor holds a value for a given
address (read or written), a descendant reading that
address does not need to add the address to its read
set.
• Nest Values.
• Nested Write Stack (NWS), which is an array indicating
which higher nesting levels hold a write for this address
•
Conflicts:
–
•
Reading a word
–
•
Push the writing Nest value on each ancestor’s NWS. If the oldest ancestor’s NWS overflows, write it to
memory.
Aborting a transaction:
–
–
–
•
Will be in the entry having the same Tid and Address, and an empty NWS (i.e., it has no descendant entries
and thus is topmost)
Writing a word
–
•
Conflicting entries are simply those whose Tid is different and whose mode (read/write) conflicts with the
action to perform.
Invalidate all entries for the Tid and Nest level.
If the Nest value matches the top of an entry’s NWS, that entry pops its NWS, discarding the NWS entry for
the aborted transaction.
In the case of an entry with Nest value 0 (which is really a transaction 0 value), we reset the Tid to 0
Committing a transaction:
–
–
–
If the committing transaction is closed and not top-level, its entries, both read and write, decrement their
Nest value
If an entry’s NWS top value equals the committing transaction’s Nest value, then it is an ancestor entry.
The ancestor decrements its top NWS value