1 / 40

Transactional Memory Guest Lecture Design of Parallel and High-Performance Computing

Transactional Memory Guest Lecture Design of Parallel and High-Performance Computing. Georg Ofenbeck. TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: A A. Locking Recap: The Problem. void PushLeft ( DQueue *q, int val ) {

nariko
Download Presentation

Transactional Memory Guest Lecture Design of Parallel and High-Performance Computing

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Transactional MemoryGuest Lecture Design of Parallel and High-Performance Computing Georg Ofenbeck TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: AA

  2. Locking Recap: The Problem voidPushLeft (DQueue*q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; QNode *LS = q->left; QNode *LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } • How to make this parallel? • Global lock to coarse grained • Fine grained locking not trivial • How to compose? Double queue ? ? ? ? LS 10 20 RS qn

  3. Locking Recap: A possible Solution voidPushLeft(DQueue*q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode *LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Transactional Memory might be a solution • Makes a code block behave like its executed as a single atomic instruction Double queue Transaction LS 10 20 RS qn

  4. Historical Background • Databases accessed concurrently for decades • “Transactions” as abstraction tool • Atomic • Consistency • Isolated • Durable • Proposed for general applications already 1977 by Lomet • Transactions on memory instead of databases Picture: http://godatabase.net

  5. Research on Transactional Memory [Number of publications] [Number of hits/10] multicore IeeeXplore

  6. Research on Software TM (STM) • IntelC++ STM compiler extends C++ with support for STM language extensions • Microsoft STM.NET is an experimental extension of the .NET Framework • Sun/OracleDSTM2 Dynamic Software Transactional Memory Library

  7. ACID voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode *LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } Double queue Transaction LS 10 20 RS

  8. AtomicityCID voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode *LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Failure atomicity • Transaction only succeeds if all its parts succeed • No evidence of its execution is left behind in case of failure • Doesnot mean atomic execution Double queue Transaction LS 10 qn

  9. AtomicityCID voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode *LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Failure atomicity • Transaction only succeeds if all its parts succeed • No evidence of its execution is left behind in case of failure • Doesnot mean atomic execution Double queue Transaction LS 10 qn

  10. AConsistencyID voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode *LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Consistency • A consistent state (e.g. links ok) is preserved when transaction ends • In case of an abort satisfied by the failure atomicity Double queue Transaction LS 10 qn

  11. ACIsolationD voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right= qn; LN->left = qn; } } • Isolation • Transaction do not interfere with each other Transaction

  12. ACIsolationD voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right= qn; LN->left = qn; } } • Isolation • Transaction do not interfere with each other Double queue qn Transaction LS 10 qn

  13. ACIDurability voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right= qn; LN->left = qn; } } • Durability • Persisting data in the database world • Sometimes relevant for Hardware TM – persisting caches to memory Transaction

  14. TM Design Choices • Failure Atomicity • How to restore the original state? • Version Control • Isolation • How to shield concurrent transactions from each other? • Concurrency Control • Consistency • How to detect conflicts? • Conflict Detection

  15. TM Design Choices • Failure Atomicity • How to restore the original state? • Version Control • Isolation • How to shield concurrent thread from each other? • Concurrency Control • Consistency • How to detect conflicts? • Conflict Detection

  16. Version Control voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Eager Version Management • Write changes directly in memory and change all values in Undo Log • On success simply remove Undo Log • On failure restore original values

  17. Version Control • Eager Version Management • Write changes directly in memory and change all values in Undo Log • On success simply remove Undo Log • On failure restore original values voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } Undo Log QNode *LS QNode *LN NULL NULL Double queue LS 10 qn

  18. Version Control voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Lazy Version Management • Write changes into a buffer and apply at commit • Apply changes during commit if no conflict occurred • Otherwise just discard buffer • Most common

  19. Version Control • Lazy Version Management • Write changes into a buffer and apply at commit • Apply changes during commit if no conflict occurred • Otherwise just discard buffer • Most common voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } Buffer Double queue LS 10 qn

  20. Version Control • Lazy Version Management • Write changes into a buffer and apply at commit • Apply changes during commit if no conflict occurred • Otherwise just discard buffer • Most common void Example () { x = 2; y = 0; atomic{ x = 3; y = x; } } Buffer x 3 ? x 2 y 0

  21. Version Control • Redirection • Explicit by library • Implicit by compiler • Overhead! voidPushLeft (DQueue *q, intval) { QNode *qn = malloc(sizeof(QNode)); qn->val = val; do{ StartTx(); QNode *LS = ReadTx(&(q->left)); QNode *oLN = ReadTx(&(LS->left)); WriteTx(&(qn->left), LS); WriteTx(&(qn->right), oLN); WriteTx(&(LS->right), qn); WriteTx(&(oLN->left), qn); } while (!CommmitTx()); }

  22. TM Design Choices • Failure Atomicity • How to restore the original state? • Version Control • Isolation • How to shield concurrent transactions from each other? • Concurrency Control • Consistency • How to detect conflicts? • Conflict Detection

  23. Concurrency Control voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Pessimistic • Transaction locks all variables it works on during a transaction

  24. Concurrency Control voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Pessimistic • Transaction locks all variables it works on during a transaction • Deadlocks! • Usually in combination with eager version managment Double queue qn LS 10 qn

  25. Concurrency Control voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Optimistic • System maintains multiple versions and detects conflict later

  26. Concurrency Control voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Optimistic • System maintains multiple versions and detects conflict later Double queue qn LS 10 qn

  27. Concurrency Control voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Optimistic • System maintains multiple versions and detects conflict later • Livelocks! Double queue qn LS 10 qn

  28. Concurrency Control voidPushLeft (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LS->right = qn; LN->left = qn; } } • Optimistic • System maintains multiple versions and detects conflict later • Livelocks! voidPushLeft2 (DQueue *q, intval) { QNode*qn = malloc(sizeof(QNode)); qn->val = val; atomic{ QNode *LS = q->left; QNode*LN = LS->right; qn->left = LS; qn->right = LN; LN->left = qn; LS->right = qn; } }

  29. TM Design Choices • Failure Atomicity • How to restore the original state? • Version Control • Isolation • How to shield concurrent transactions from each other? • Concurrency Control • Consistency • How to detect conflicts? • Conflict Detection

  30. Conflict detection • Granularity • Bytes, Objects …. • How to resolve? • Control to user? (Exception like) • RetryDelayedPriorities …. • For optimistic concurrency • When to check? • Eager conflict detection? • How to detect? void Example (int input) { atomic{ x = input; y = x; } }

  31. Nesting • Flattened Nesting • Closed Nesting • Open Nesting void Example () { x = 2; y = 0; atomic{ x = 3; y = x; atomic{ z = 3*x; w = z--; } } }

  32. Why do we bother with locks? Source:CalinCascaval, Colin Blundell, Maged Michael, Harold W. Cain, Peng Wu, Stefanie Chiras, Siddhartha Chatterjee, 2008. Software Transactional Memory: Why Is It Only a Research Toy?.Queue 6, 5 (September 2008)

  33. Why do we bother with locks? Source:CalinCascaval, Colin Blundell, Maged Michael, Harold W. Cain, Peng Wu, Stefanie Chiras, Siddhartha Chatterjee, 2008. Software Transactional Memory: Why Is It Only a Research Toy?.Queue 6, 5 (September 2008)

  34. Why do we bother with locks? Source:AleksandarDragojević , Pascal Felber , Vincent Gramoli , RachidGuerraoui, Why STM can be more than a research toy, Communications of the ACM, v.54 n.4, April 2011

  35. Why do we bother with locks? Source:FeradZyulkyarov, Vladimir Gajinov, Osman S. Unsal, Adrián Cristal, Eduard Ayguadé, Tim Harris, and Mateo Valero. 2009. Atomic quake: using transactional memory in an interactive multiplayer game server.

  36. Why do we bother with locks? Source:FeradZyulkyarov, Vladimir Gajinov, Osman S. Unsal, Adrián Cristal, Eduard Ayguadé, Tim Harris, and Mateo Valero. 2009. Atomic quake: using transactional memory in an interactive multiplayer game server.

  37. Why do we bother with locks? [Number of publications] [Number of hits/10] IeeeXplore

  38. Why do we bother with locks? • IntelC++ STM compiler extends C++ with support for STM language extensions • Microsoft STM.NET is an experimental extension of the .NET Framework discontinued

  39. Summary • TM is a nice model to tackle parallelism BUT • STM does not yield good performance • HTM often with only limited functionality and hard to instrument • Hybrids the future? • Issues not covered in this lecture • Details of conflict detection • How to handle I/O? • How to handle access from outside of the transaction? • ….

  40. More information • Transactional Memory, 2nd Edition (Synthesis Lectures on Computer Architecture)

More Related