Multicore programming

Slides:



Advertisements
Similar presentations
CS 11 C track: lecture 7 Last week: structs, typedef, linked lists This week: hash tables more on the C preprocessor extern const.
Advertisements

Lecture 11 oct 6 Goals: hashing hash functions chaining closed hashing application of hashing.
Threading Part 3 CS221 – 4/24/09. Teacher Survey Fill out the survey in next week’s lab You will be asked to assess: – The Course – The Teacher – The.
hashing1 Hashing It’s not just for breakfast anymore!
5.6 Semaphores Semaphores –Software construct that can be used to enforce mutual exclusion –Contains a protected variable Can be accessed only via wait.
Lecture 11 oct 7 Goals: hashing hash functions chaining closed hashing application of hashing.
L. Grewe. Computing hash function for a string Horner’s rule: (( … (a 0 x + a 1 ) x + a 2 ) x + … + a n-2 )x + a n-1 ) int hash( const string & key )
(c) University of Washingtonhashing-1 CSC 143 Java Hashing Set Implementation via Hashing.
HASHING Section 12.7 (P ). HASHING - have already seen binary and linear search and discussed when they might be useful (based on complexity)
Optimistic Design 1. Guarded Methods Do something based on the fact that one or more objects have particular states  Make a set of purchases assuming.
© 2004 Goodrich, Tamassia Hash Tables1  
Stack Overview. Stack Stack ADT Basic operations of stack – Pushing, popping etc. Implementations of stacks using – array – linked list.
“Never doubt that a small group of thoughtful, committed people can change the world. Indeed, it is the only thing that ever has.” – Margaret Meade Thought.
Lecture 9 : Concurrent Data Structures Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit.
Fundamental Structures of Computer Science II
CSCI 210 Data Structures and Algorithms
Week 8 - Wednesday CS221.
Faster Data Structures in Transactional Memory using Three Paths
Data Structures and Algorithms for Information Processing
Lecture 25 More Synchronized Data and Producer/Consumer Relationship
CSC 427: Data Structures and Algorithm Analysis
Concepts of programming languages
Hashing CS2110 Spring 2018.
CS313D: Advanced Programming Language
Circular Buffers, Linked Lists
More Data Structures (Part 1)
Hashing II CS2110 Spring 2018.
Concurrent Data Structures Concurrent Algorithms 2017
Synchronization Lecture 23 – Fall 2017.
Computer Science 2 Hashing
Introduction to Database Systems
Hash Tables.
Hashing CS2110.
Lock-Free concurrent algorithm for Linked lists: Implementation
Data structures in C++.
Resolving collisions: Open addressing
Concurrent Hashing and Natural Parallelism
Introduction to Database Systems
Searching Tables Table: sequence of (key,information) pairs
slides created by Marty Stepp and Hélène Martin
CH 9.2 : Hash Tables Acknowledgement: These slides are adapted from slides provided with Data Structures and Algorithms in C++, Goodrich, Tamassia and.
slides adapted from Marty Stepp and Hélène Martin
Multicore programming
Hash Tables Chapter 12 discusses several ways of storing information in an array, and later searching for the information. Hash tables are a common.
Tim Ehrlich Growing Arrays in C.
Dictionaries 1/17/2019 7:55 AM Hash Tables   4
CH 9.2 : Hash Tables Acknowledgement: These slides are adapted from slides provided with Data Structures and Algorithms in C++, Goodrich, Tamassia and.
Multicore programming
Multicore programming
Multicore programming
Multicore programming
Hash Tables Computer Science and Engineering
Computer Science 2 Hashing.
Hash Tables Computer Science and Engineering
CS210- Lecture 5 Jun 9, 2005 Agenda Queues
Multicore programming
Hash Tables Chapter 12 discusses several ways of storing information in an array, and later searching for the information. Hash tables are a common.
Multicore programming
CSC 143 Java Linked Lists.
Multicore programming
Multicore programming
Hashing in java.util
Collision Handling Collisions occur when different elements are mapped to the same cell.
CS210- Lecture 16 July 11, 2005 Agenda Maps and Dictionaries Map ADT
slides created by Marty Stepp and Hélène Martin
CSE 451 Section 1/27/2000.
slides created by Ethan Apter and Marty Stepp
EECE.3220 Data Structures Instructor: Dr. Michael Geiger Spring 2019
CSE 373: Data Structures and Algorithms
Presentation transcript:

Multicore programming Unordered sets: concurrent hash tables Week 3 - Monday Trevor Brown http://tbrown.pro

Last time Fixed size, probing hashtables With deletion (using tombstones)

How tombstones fix our problem Insert(7) hashes to 2 Insert(3) hashes to 5 7 9 3 Insert(9) hashes to 2 Delete(7) hashes to 2 Delete(9) hashes to 2

Downsides of tombstones? TOMBSTONEs are never cleaned up Cleaning them up seems hard Cannot remove a TOMBSTONE until there are no keys in the table that probed past the TOMBSTONE when they were inserted Thought: if we do table expansion, there’s no need to copy over TOMBSTONEs… 9 3 Probes when 9 was inserted

Efficiently Expanding a hash table Concurrent Hash Tables: Fast and General(?)! [MSD2016] Issues to solve When to expand? Too much probing? Estimate of table size vs capacity? Which threads will perform the expansion? Enslaving user threads that access the table? Custom thread pool? How to expand? Block updates when expansion is happening? Always allow updates? Hard to always allow updates “we are fine with small amounts of (b)locking, as long as it improves the overall performance” (a healthy attitude)

High level idea When estimated size > 50% of table size, expand by 2x & migrate contents into the new table Naïve idea: global lock on table, copy with one thread --- inefficient! Partition old table into chunks (default size 4096) Numbered 0, 1, 2, …, floor(capacity / 4096) Threads use fetch & add to claim chunks they will migrate Migrate a chunk to the new table by performing insert() on each key

What if expansion is Concurrent with updates? 1 2 Thread 1: F&A to claim a chunk chunksClaimed Thread 2: F&A to claim a chunk Thread 1 Thread 2 Thread 1: see bucket 0 is empty Thread 1: copy bucket 1 (val 6) Old table 9 6 3 4 2 Thread 3: insert 9 at index 0 Threads 1&2: finish expansion Lost key 9! Must prevent updates to cells we’ve already migrated! New table 6 3 4 2

Solution: marking Steal a bit from each key field Use it to store a mark Invariant: a bucket with a marked key cannot be modified In expansion, mark each bucket before migrating it currKey = bucket->key CAS(bucket->key, currKey, currKey | MARKED_MASK) In insert/delete, before performing CAS(bucket->key, currKey, newKey), must verify that old is not marked (otherwise, help with expansion) Could we use a write to mark the bucket, instead of CAS? unmarked marked 7 7 X

How marking helps 1 2 Thread 1: F&A to claim a chunk chunksClaimed Thread 1: F&A to claim a chunk chunksClaimed Thread 2: F&A to claim a chunk Thread 1 Thread 2 Thread 1: mark bucket 0 Thread 1: mark & copy bucket 1 Old table 6 3 4 2 X X Thread 3: try insert(9) @ idx0 CAS(&bucket[0]->key, <NULL, unmarked>, <9, unmarked>) CAS FAILS! New table 6 Thread 3: help expansion (if there are any unclaimed chunks) After expansion, retry insert(9)

Detecting table > 50% full Approximate counter: Global data: volatile int size Per-thread data: int numInserts When a thread inserts, it increments its own private numInserts After a thread does Ω(𝑛𝑢𝑚𝑇ℎ𝑟𝑒𝑎𝑑s) increments, it does Fetch&Add(&size, numInserts) then sets its private numInserts to 0 How far off can size be from the true value? 𝐸𝑟𝑟𝑜𝑟=𝑐⋅𝑛𝑢𝑚𝑇ℎ𝑟𝑒𝑎𝑑 𝑠 2 Insignificant for large tables (for c=1, 100 threads, error is 10000: 1% of 1M keys) Could we do better? Reduces contention on size vs F&A every time

Implementation sketch With expansion struct hashmap 1 volatile char padding0[64]; 2 table * volatile currentTable; 3 volatile char padding1[64]; /* code for operations ... */ Without expansion struct hashmap 1 volatile char padding0[64]; 2 volatile uint64_t * data; 3 const int capacity; 4 volatile char padding1[64]; /* code for operations ... */ struct table 1 volatile char padding0[64]; 2 volatile uint64_t * data; 3 volatile uint64_t * old; 4 volatile int chunksClaimed; 5 volatile int size; 6 const int capacity; 7 volatile char padding1[64];

Implementation sketch Check if expansion is in progress, and help if so. Otherwise, create new struct table and CAS it into currentTable. int hashmap::insert(int key) table * t = currentTable; int h = hash(key); for (int i=0;i<capacity;++i) { if (isTooFull(t)) { tryExpand(); return insert(key); } int index = (h+i) % t->capacity; int found = t->data[index]; if (found & MARKED_MASK) { helpExpand(); return insert(key); } else if (found == key) return false; else if (found == NULL) { if (CAS(&t->data[index], NULL, key)) return true; else { found = t->data[index]; } } } assert(false); Check if expansion is in progress, and help if so. Check if expansion is in progress, and help if so. Could fail CAS become someone inserted, or because someone marked

Summary Deletion in concurrent hash tables Expansion of concurrent hash tables Padding to avoid false sharing in the hash table At the start & end of the hash table struct/class At the start & end of the data array Not padding each bucket!