1 / 78

Lecture 9 : Concurrent Data Structures

Lecture 9 : Concurrent Data Structures. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit. Concurrent Data Structures. We assume shared-memory multiprocessors environment

Download Presentation

Lecture 9 : Concurrent Data Structures

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. Lecture 9 : Concurrent Data Structures Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

  2. Concurrent Data Structures • We assume • shared-memory multiprocessors environment • concurrently execute multiple threads which communicate and synchronize through data structures in shared memory

  3. Concurrent Data Structures : Issues • Far more difficult to design than sequential ones • Correctness • Primary source of difficulty is concurrency • The steps of different threads can be interleaved arbitrarily • Scalability (high performance)

  4. Lock Granularity • Coarse grained locking • Simple & Easy • Sequential bottleneck Problem • at most one thread does useful work • Fine grained locking • Improve the problem of sequential bottleneck (i.e. multiple threades wait for a working thread)

  5. Example • Concurrent linked list • Coarse grained locking • Fine grained locking • Scalable counter

  6. List-Based Sets We assume data are sorted in list. public interface Set<T> { public booleanadd(T x); publicbooleanremove(T x); publicbooleancontains(T x); }

  7. List Node public class Node { public T item; // item of interest publicint key; // usually hash code public Node next; // reference to next node }

  8. b a c The List-Based Set -∞ +∞ Sorted with Sentinel nodes (min & max possible keys)

  9. Sequential List Based Set Add() a d c Remove() a c b

  10. Sequential List Based Set Add() a d c b Remove() a c b

  11. Course Grained Locking a d b

  12. Course Grained Locking a d b c

  13. Course Grained Locking a d b honk! honk! c Simple but hotspot + bottleneck

  14. Coarse-Grained Synchronization • Sequential bottleneck • Threads “stand in line” • Adding more threads • Does not improve throughput • Struggle to keep it from getting worse • So why even use a multiprocessor? • Well, some apps inherently parallel …

  15. Coarse-Grained Synchronization(Linked List) public boolean add(T item) { Node pred, curr; int key = item.hashCode(); lock.lock(); try { pred = head; curr = pred.next; while (curr.key < key) { pred = curr; curr = curr.next; } if (key == curr.key) { return false; } else { Node node = new Node(item); node.next = curr; pred.next = node; return true; } } finally { lock.unlock(); } } public class CoarseList<T> { private Node head; private Node tail; private Lock lock = new ReentrantLock(); public CoarseList() { // Add sentinels to start and end head = new Node(Integer.MIN_VALUE); tail = new Node(Integer.MAX_VALUE); head.next = this.tail; }

  16. public boolean remove(T item) { Node pred, curr; int key = item.hashCode(); lock.lock(); try { pred = this.head; curr = pred.next; while (curr.key < key) { pred = curr; curr = curr.next; } if (key == curr.key) pred.next = curr.next; return true; } else { return false; } } finally { lock.unlock(); } } public boolean contains(T item) { Node pred, curr; int key = item.hashCode(); lock.lock(); try { pred = head; curr = pred.next; while (curr.key < key) { pred = curr; curr = curr.next; } return (key == curr.key); } finally { lock.unlock(); } }

  17. Coarse-Grained Locking • Easy, same as synchronized methods • “One lock to rule them all …” • Simple, clearly correct • Deserves respect! • Works poorly with contention

  18. Performance Improvement • For highly-concurrent objects • Goal: • Concurrent access • More threads, more throughput

  19. First:Fine-Grained Synchronization • Instead of using a single lock .. • Split object into • Independently-synchronized components • Methods conflict when they access • The same component … • At the same time

  20. Second:Optimistic Synchronization • Search without locking … • If you find it, lock and check … • OK: we are done • Oops: start over • Evaluation • Usually cheaper than locking • Mistakes are expensive

  21. Third:Lazy Synchronization • Postpone hard work • Removing components is tricky • Logical removal • Mark component to be deleted • Physical removal • Do what needs to be done

  22. Fine-grained Locking • Requires careful thought • “Do not meddle in the affairs of wizards, for they are subtle and quick to anger” • Split object into pieces • Each piece has own lock • Methods that work on disjoint pieces need not exclude each other

  23. Fine-grained Locking • Use multiple locks of small granularity to protect different parts of the data structure • Goal • To allow concurrent operations to proceed in parallel when they do not access the same parts of the data structure

  24. b a c Hand-over-Hand locking

  25. b a c Hand-over-Hand locking

  26. b a c Hand-over-Hand locking

  27. b a c Hand-over-Hand locking

  28. b a c Hand-over-Hand locking

  29. b d a c Removing a Node remove(b)

  30. b d a c Removing a Node remove(b)

  31. b d a c Removing a Node remove(b)

  32. b d a c Removing a Node remove(b)

  33. b d a c Removing a Node remove(b)

  34. d a c Removing a Node Why do we need to always hold 2 locks? remove(b)

  35. b d a c Concurrent Removes remove(c) remove(b)

  36. b d a c Concurrent Removes remove(c) remove(b)

  37. b d a c Concurrent Removes remove(c) remove(b)

  38. b d a c Concurrent Removes remove(c) remove(b)

  39. b d a c Concurrent Removes remove(c) remove(b)

  40. b d a c Concurrent Removes remove(c) remove(b)

  41. b d a c Concurrent Removes remove(c) remove(b)

  42. b d a c Concurrent Removes remove(c) remove(b)

  43. d a c Uh, Oh remove(c) remove(b) Art of Multiprocessor Programming

  44. d a c Uh, Oh Bad news, C not removed remove(c) remove(b)

  45. b a c c Problem • To delete node c • Swing node b’s next field to d • Problem is, • Someone deleting b concurrently could direct a pointer to c a b

  46. Insight • If a node is locked • No one can delete node’s successor • If a thread locks • Node to be deleted • And its predecessor • Then it works

  47. b d a c Hand-Over-Hand Again remove(b)

  48. b d a c Hand-Over-Hand Again remove(b)

  49. b d a c Hand-Over-Hand Again remove(b)

  50. b d a c Hand-Over-Hand Again Found it! remove(b)

More Related